Threads for GeoffWozniak

  1. 5

    I did not see a link to Doug Zongker’s classic paper and presentation.

    1. 1

      Ok I just read the paper and the link I posted is clearly derivative as well as somewhat reductionist. Compared to the original work done by Zongker, this is a mere shadow. Also watched the talk and found the Q&A to really be something to chew on.

    1. 18

      I have flagged all of them as off-topic. As for why they have not been removed I can’t say since I am not a moderator. I have my say with the flags.

      To answer your question, I think many submissions about social media are off-topic, but they must be judged on a case by case basis.

      1. 3

        I wrote the “Three things to like about the Fediverse”.

        Some say it is low quality because it only contains three bullet points. But it took me quite a while to distill the essence of what is good about the Fediverse down to what I consider the three main points.

        The reason I posted it here is that all three are benefits for developers.

        Owning your identity like you own your domain is something easy for developers. Not so easy for regular users. Although that will probably change over time.

        Fully customizing your experience can only be done by developers. As it means you have to customize the code of your instance.

        Building cool stuff on top of it is also something that can only be done by developers. As it means to build new software.

        1. 10

          The three “main points” are devoid of any meaningful content, personally:

          • Do you “own” a domain? You’re registered as the owner of a domain, but it’s not really ownership, it’s a lease from IANA or whoever. So what does it actually mean from a technical perspective to “own” your federated identity? There is no knowledge gained from reading this bullet point.
          • “Fundamentally open” would be cited as weasel words on Wikipedia. What’s open? You don’t need a FOSS instance to have a federated instance. So the ActivityPub protocol is open? That’s great, but ActivityPub is a standardised protocol - “customise your experience” doesn’t particularly mean much in regards to that. It’s a point that’s been distilled of all information.
          • I guess you can “build cool stuff” on top of anything with a big enough hammer, but on ActivityPub/Mastodon/Pleroma that’s fair. This again though is a point distilled of all information, there’s nothing you learn, nothing one gains from reading it.

          Hope this gives some perspective on why people, or at least I, would have downvoted your submission or considered it off-topic (lacking technical content). It’s nothing personal, I’m sure your tweets are great and you have technical information, technical knowledge etc. you could share in the future.

          1. 3

            There is a lot to unpack here. Let me start with the first point:

            You are always at the mercy of some infrastructure providers. That is why in my Tweet, I wrote “You can own your identity to the same degree you can own a domain”.

            IANA, ICANN, your registrar, browser vendors, operating system vendors .. they all have the power to interfere with how available a specific domain is. But these infrastructure providers are generally orders of magnitude more trustworthy than social networks. How often did you hear that one of these infrastructure providers interfered with a single domain? I can remember almost no such events. On social networks on the other hand, interference with visibility is the norm. Even outright deplatforming is pretty common.

            So owning your identity to the same degree you own a domain is a big step forward.

            When decentralized domain name systems like .eth become supported, you can own a domain to an even higher degree. By being the only one who knows the secret key that holds the power over your domain. That would cut IANA, ICANN and your registrar out of the loop.

            1. 2

              How often did you hear that one of these infrastructure providers interfered with a single domain?

              It happened to a website which shall not be named just the other day (recency bias? I’d have to look for other examples.) Your identity is now also subject to potential hijacking or squatting. Not having a process you can turn to and recover your stolen identity is a huge step backwards.

              Side note: I think it’s a good thing that social networks interfere with visibility of certain content, and federated social media does so in very broad strokes (example). De-platforming and censorship are social debates, and debates not solved or avoided through federation.

              1. 1

                Can you elaborate on what you mean by potential hijacking or squatting?

        2. 1

          As for why they have not been removed I can’t say since I am not a moderator.

          When I ask whether they should be removed, that is more so a metaphorical question (to everyone but the admin) as to whether the community would appreciate those topics being submitted. I especially wanted to hear from people who had been around for a while, because there was a significant amount of disagreement between users upvoting and flagging the articles. A better question to ask would have been: Should I, and other newcomers like myself, be submitting stories related to social media?

          Your answer, as I understand it, is: No, unless there is heavy technical content within. For example, an article describing the logistics behind running a social media database would be okay.

          If you have a moment, I’d also like to ask about the nuances of your answer. I’ve also run across a few similar, older posts with no flags:

          Do you think these posts are on topic? If so, what makes them different from the posts in my original post?

          1. 4

            The first is more a community information exchange than anything else, so I’m okay with it. It’s analogous to a bunch of us meeting up and informally exchanging business cards,

            The second is off-topic to me. I’d flag it, but it was submitted two years ago so there’s no point. I don’t think this is the place to be discussing the distribution of Mastodon and what it means for online communities.

        1. 7

          Always be upgrading!

          This is profoundly wasteful and should not be encouraged.

          I upgraded my CPU a couple years ago but I made a mistake and bought one that didn’t support ECC RAM because I misread the specs (which is easier to do than one may think). This last month I decided to update the CPU and get the ECC RAM. Turns out upgrading the CPU caused thermal problems and I ended up having to get a cooling unit which I then found did not fit in my case, so I had to get a new case as well. I had to refit the whole setup for my desk as the final kicker.

          I probably should have thrown in the towel when the CPU was having thermal problems, but I was stupidly stubborn. Now I’ve spent considerably more than I was hoping for a setup that is only marginally better than it was before. And I have a CPU and RAM that I could sell, but they’re not worth very much and the hassle of selling it seems like a waste of my time.

          “Always be upgrading” is a great way to produce a bunch of e-waste that we would be better off without. I hope to not have to update anything for about 7-10 years. If an 8-core home server with 64GB of (ECC) RAM is not enough for home computing needs in that time, we’re probably doing something very wrong.

          (Side note: gaming culture has made hardware purchasing a total mess. I hope it fades into the sunset some day.)

          1. 4

            This is profoundly wasteful and should not be encouraged.

            Agreed. To be clear - the “always be upgrading” was meant as a light joke (and a reference to learning as a form of self-upgrade) to wrap up the article on a positive note. :-)

            I think of upgradeability as something good, that actually reduces waste, but not something we should be doing all the time. E.g. I’d normally do a CPU upgrade every 4-5 years, but sadly no motherboards have a lifespan that long.

            1. 3

              AM4 socket motherboards were supposed to, but AMD broke compatibility in the middle of AM4’s lifetime. I’m hoping they don’t make the same mistake with AM5.

              Intel sockets change every 5 minutes though. No chance there.

              1. 2

                It’s surprising that AMD would make that mistake given their history. They gained a lot of market share during the era when they supported ‘super 7’ (socket 7 with a few minor tweaks) for CPUs from 133-450MHz, with the same RAM (though you wanted to upgrade to a faster clock ideally), while Intel was pushing everyone to Slot 1 and RAMBUS memory.

                1. 1

                  The times have been good for AMD recently, so perhaps they decided they have the upper hand this time around. Personally, I don’t see any major advantages of DDR5 over DDR4, and I’m in no rush to switch to it.

                2. 1

                  Fair point about Intel. I honestly don’t get why they need new sockets every couple of years. I was definitely very disappointed when AM5 was announced, when I originally expected that Zen 3 would be targeting AM4. And now that AM5 doesn’t support DDR4, changing the CPU means changing the MB + the CPU + RAM, which is almost a new PC. At least they said that all the MB dimensions are exactly the same, so coolers for AM4 would fit fine AM5.

                  I do think the main reason for the constant Platform upgrades is to appease the vendors of MBs, RAM, etc - they want to sell something all the time, not every 5 years. There are many players in the computer hardware world and everyone wants their cut.

              2. 1

                I just built a gaming computer for my brother to last 10+ years. Planned upgrade of CPU in ~5 years, whenever the last AM5 CPU is released. GPU as needed, whenever prices are good. Every other part of the machine I picked to last through those upgrades. Always plan for upgrades to minimize e-waste. Few gaming PCs live 10+ years for exactly the reason you describe.

                1. 1

                  That’s a solid plan, hopefully the last AM5 cheap won’t be released 2 years from now. I guess I’ll stick with my current CPU for a couple of years more, and then I’ll evaluate my options. I still have high hopes for Intel 4 and Meteor Lake. I love AMD, but I really want Intel to get their act together and build something great again.

                  Btw, AMD did make the vague announcement that they “are going to support AM4” for many years to come, whatever this means.

                  1. 1

                    Firmware support maybe? The Windows 11 stutter issue was only patched a few months ago.

                    1. 1

                      I thought as much, although they might have another “special edition” of the Ryzen 5000 lineup in their plans - e.g. some Ryzen 5900X3d or something like this.

              1. 27

                Perhaps Rust should just take existing references and put them in a “Rust Standard.pdf” document with a note that anything not here is implementation-defined. It doesn’t have to be 100% comprehensive. C barely says what happens when you add two ints, and ISO OOXML got away with things like “render like word95” without further elaboration.

                1. 17

                  Yeah, this point about Rust not having a “specification” is getting tiresome. Very few languages have actual formal specifications with operational semantics that govern how they should work. SML is the only generally useful one I can think of.

                  From the article:

                  While we do have a reference that explains what features are stable and many of the guarantees of the language, it is not a complete specification.

                  What does the author feel is missing? There are no concrete examples, just a general statement.

                  I like pcwaltons approach here, which is basically just to rename the reference to “The Rust Specification” and then get people to shut up.

                  1. 13

                    A lot of things are missing completely, as far as I understand:

                    • name resolution
                    • type inference
                    • trait resolution
                    • lifetime inference and checking
                    1. 2

                      Thank you, those are indeed missing.

                    2. 10

                      The memory model is missing. That’s a problem actively being worked on, but it’s probably the part of the language that is worst defined, because it isn’t even implementation defined.

                      I think it’s also incomplete in C though (see work on PNVI), so that’s fun.

                      1. 5

                        I don’t agree with pcwalton fully here, particularly having looked at the reference from the perspective of someone in need of a specification (for Rust in safety critical). The reference is lacking both in content and in an important feature: traceability - it is hard to differentiate features in it that can be traced as requirements. Yes, the specification that we ended up writing is based on the Reference - it’s a great document to start with. https://spec.ferrocene.dev/general.html#general

                        By and large, too much of this discussion is controlled a) by a poor understanding that specifications can be a useful communication document and don’t need to be boring to read and b) seeing specification efforts through the experience of the C/C++ standardisation methodologies.

                        1. 2

                          Formal operational semantics of JavaScript, tested against test262 test suite, also exists: https://jscert.org/

                          1. 11

                            First of all, wtf?

                            Top South Africa’s Top No Deposit Casinos. If you want to find some of the best online casinos that South Africa has to offer, where you can take advantage of a juicy no deposit bonus code, then you’re in the right place.

                            Secondly, there’s a variety of efforts to define similar formal semantics for Rust, just like CompCert exists for C. I think that’s beside the point: Those efforts are not what define the language, they are ex post efforts to make sense of whatever defines the language. In the case of JavaScript this is the defining specification.

                        2. 6

                          and put them in a “Rust Standard.pdf” document

                          I agree, but please we need to stop with the whole obsession with PDF documents for tech documentation. They’re just old-school and awkward to read on different devices. We invented hypertext documents for a reason, let’s use them! No one is printing off specifications and reading them on a couch by the fire anymore.

                          I feel like organisations/people choose PDFs to give their writing some kind of feeling of superiority, like how all the crypto scams projects release a wHiTePaPeR which is most of the time just a documentation web page printed into a PDF file.

                          1. 24

                            They’re just old-school and awkward to read on different devices.

                            As someone who is looking at hardware documentation, ABI documentation, and various other standards a lot of the time, I still prefer PDFs because I don’t get variety in presentation. Figures look correct, things are generally aligned properly, and they are easier to share across internal networks. If I’m going to get a standards document, I don’t want it to be dependent on network access, nor do I want it to be a bundle of different files. Documentation in PDF form is almost always a single file. This makes search across the entire document simple. Also, if you do need to print parts of them (yes, it happens), the output will almost certainly match the display.

                            Hyperlinking in a PDF has worked for a long time, and any viewer I’ve used in the past 20 years supports such navigation.

                            PDFs are awkward to read on some devices, but they are still used because they are predictable and are more permanent. It has nothing to do with “a feeling of superiority” and more to do with online documentation constantly shifting.

                            1. 3

                              If I’m going to get a standards document, I don’t want it to be dependent on network access, nor do I want it to be a bundle of different files.

                              EPUB is almost always a better choice than PDF these days. Yes, presentation can vary, but that’s a legitimate trade-off. PDFs often aren’t readable on anything where the screen won’t fit a letter-sized page in portrait orientation; with an EPUB you get readability on any device, in a single file, without network access being required. I admit that you lose things from PDF (predictable layout; screen layout being identical to print layout), but I think the trade-offs are usually worth it.

                              1. 8

                                It’s alway a pain for me to read EPUBs on desktop. I never got around to finding a client or setup which I either like or “just works” and has sensible defaults. Where as decent, built-in PDFs clients are often right there. (A part of may be I have never been motivated to dive down the rabbit hole when I can just lean on my mobile clients)

                                1. 3

                                  I feel the same about PDF on mobile, though.

                                  For desktop, the easiest thing is to install a browser extension for EPUBs. On Linux and similar, Foliate is the best “just works” reader. I don’t know about MacOS and Windows.

                                  1. 1

                                    Kindle on iPad was great for PDF until they gimped some point after Apr. 2021. Now you don’t get ToC or even the ability to zoom out (no reading progress too? I don’t remember)

                                    1. 0

                                      In some cases, it can be beneficial if a document is annoying to read on phones.

                                    2. 1

                                      I never got around to finding a client or setup which I either like or “just works” and has sensible defaults.

                                      Seconded. I’ve tried a few different ones and the display has been hideous. And for some reason navigation was a mess.

                                  2. 1

                                    HTML can totally be put in a single offline-usable file. And looking different on different screen is a good thing.

                                  3. 4

                                    Actually the people that read entire specifications are exactly the kind of people that print them off and read them on a couch by the fire. I certainly do (well, except for the fire - that’s not recommended for improving air quality in a densely populated city!).

                                    (Though I still agree with your point, adding a legible print view to a hypertext document is much easier than the inverse)

                                  4. 1

                                    C barely says what happens when you add two ints

                                    Are you saying that the various C standards and specifications are less detailed and comprehensive than the Rust reference?

                                    1. 1

                                      It doesn’t define how the sign bit is stored. It doesn’t define how it overflows. It doesn’t dictate a specific size, only a range of sizes with details left up to the vendors. The Rust language specifies all of these things more precisely.

                                      The C spec has a lot to say, but leaves a lot of things vague and vendor specific. In C you aren’t even supposed to expect bytes to have 8 bits.

                                      1. 1

                                        But that’s not a lack of detail in the spec, it’s an explicit decision not to specify certain things in order support a wider range of hardware without affecting performance (for example). I don’t think it means the C standards are less deserving of being called standards or specifications than the Rust reference, do you?

                                        One might also ask why Rust decided to call it a reference and not a spec or standard.

                                        1. 1

                                          I’m not saying it’s not a standard, just that it barely defines what int addition is. Rust has a tendency to go for perfectionism, but that’s not necessary. Rust could also make an explicit decision to leave large “implementation-specific” gaps and still call it a spec. Or go the MS OOXML route and get ISO rubber-stamp that whatever the existing implementation does is the standard.

                                          1. 1

                                            I’m not saying it’s not a standard, just that it barely defines what int addition is.

                                            Then I don’t see the relevance. Are you saying the Rust reference gets points towards being considered a standard, because it specifies things that are deliberately unspecified in another language that has a standard?

                                            Rust could also make an explicit decision to leave large “implementation-specific” gaps and still call it a spec.

                                            People would make fun of it if the only reason for the implementation-specific gaps was laziness in documentation.

                                  1. 2

                                    I don’t know LLVM’s register allocator, nor do I know GCC’s all that well, but this kind of register allocation is very specific. Straight line code for an entire function with a lot of computation isn’t all that common. Specializing the register allocator to deal with this is probably not worth the time.

                                    Also, it wasn’t clear to me that the comparison with Clang/LLVM and GCC is all that fair because the SSRA doesn’t appear to be taking the calling convention into account. In the example

                                    r12 = INPUT0()
                                    r2 = MUL_IMM(r12)
                                    

                                    if MUL_IMM is a function, then the argument has to be passed in r0. I didn’t see anything about that in the description of the algorithm or the code. Maybe I missed it.

                                    If MUL_IMM is not a function, then the comparison is not a fair one for the same reason: LLVM and GCC are bound by the calling convention of the ABI.

                                    1. 3

                                      Since the author mentions LuaJIT uses reverse linear scan too, I guess the implication is that the same concept can be extended to support more complicated control flow as well. The linked article does not go into a lot of detail, but it says this:

                                      In LuaJIT, the IR maintains its SSA form - there is only a single definition of a value. This means that when iterating in reverse order, computing the live range becomes trivial. When we first encounter a use of a value, then by definition that is the last use. And when we encounter a definition, that is the only and single definition, and we can release the register. So there’s no need to compute the live range in advance of allocation.

                                      Furthermore, rather than merging the values of multiple branches into the same live range, each value on either side becomes an individual live range. As a result, the live range of a value never has a hole, further simplifying code.

                                      1. 4

                                        LuaJIT is a tracing JIT, so it too doesn’t have control flow.

                                      2. 2

                                        My understanding is that there are no calls here. It is for code without any jumps or branches. Calls are a kind of jumps.

                                        Yes, I agree it is a quite specific case.

                                        1. 3

                                          My understanding is that there are no calls here. It is for code without any jumps or branches. Calls are a kind of jumps.

                                          That was my understanding as well, in which case the comparison to LLVM and GCC is invalid since that is nothing but jumps.

                                      1. 8

                                        As a satisfied git user, this seems fair. The tldr is: fossil uses substantially the same data structure as git but makes completely opposite choices because it’s optimized for smaller development teams.

                                        I’d love to hear from someone who has used both extensively and prefers fossil. What’s it like? What’s lost that git users rely on? What huge wins does fossil open up?

                                        1. 8

                                          I actually go so far as to just use Fossil for most of my websites. The wiki in markdown mode works great for my sites.

                                          What’s lost that git users rely on?

                                          The big thing is, git allows mutability, in fact all of git is basically a big fungible ball of mud. Fossil is much more immutable. If you think your VCS should allow mutable history, Git is for you. If you think your commits are immutable history, you should take a serious look at Fossil. I’m not sure there is a “right” answer here, it just depends on your perspective. Personally I’m an immutable person, that does mean you get the occasional commit message that looks like: ‘oops, fix typo’. But you can be fairly confident Fossil’s history is what actually happened and not a cleaned up version of reality.

                                          1. 11

                                            For what it’s worth, the commit graph in git is immutable. The only thing mutable are the references. What’s different is that in git you can move the references however you please, with no restrictions to move them along the edges of the commit graph.

                                            In fossil, you can only converge the timelines. In git, you can jump between them.

                                            1. 7

                                              A big realization for me was that the git graph itself is versioned in the reflog. Using git reflog to restore old references is hugely valuable and I’m way more confident using git because of it. But to be fair, those commits are only stored on my local machine, will eventually be gc-ed and won’t be pushed to a remote. Fossil would track them everywhere.

                                            2. 6

                                              Could you elaborate a bit on the value of immutability to you? I fall into the mutability camp because I find the additional context is rarely worth the value when it costs so much to untangle. I’d rather use the mutability to create untangled context and have that be the only artifact that remains. I’m not disagreeing that the immutability has value to you, I’m just seeking understanding since I experience things differently.

                                              1. 5

                                                I generally have two diametrically opposed views on immutability:

                                                • In other people’s repos, I want immutability with no exceptions. If I clone your repo, nothing you do should be able to modify the history that I think I have, so I can always find a common ancestor between your version and my fork and merge back or pull in new changes.
                                                • In my own repo, I want the flexibility to change whatever I want, commit WIP things, move fixes back to the commit that introduced the bug, and so on.

                                                I think GitHub’s branch protection rules are a good way of reconciling this. The main branch enforces immutable history, as do release branches. Ideally tags would also be immutable. Anything else is the wild west: if you work from those branches then don’t expect them to still exist upstream next time you pull and you may need to resolve conflicts later. I’d like a UI that made this distinction a lot more visible.

                                                1. 2

                                                  This is definitely a reasonable perspective.

                                                  Question, what is the point of committing WIP stuff?

                                                  1. 3

                                                    Locally, so that I have an undo button that works across files, so once something is working and I want to clean it up, I can always see what I’ve changed and broken during cleanup.

                                                    Publicly, so that I can get feedback (from humans or CI), incorporate it, and then clean up the result so that, when it’s merged, everything in the history is expected to be working. This means that other people can bisect to find things that broke and not have to work out if a particular version is expectedly or unexpectedly broken. It also means that people merging don’t see conflicts in places where I made a change in a file, discovered I didn’t need it, reverted it, and they did a real change in that location.

                                                    1. 1

                                                      Thanks!

                                                      For me and us @ $WORK, the undo button is either ZFS snapshots(exposed as ~/.snapshots) or $EDITOR’s undo functionality.

                                                      For human feedback, we have a shared user machine we work from or we use other more general purpose tools, like desktop screen sharing(typically tmux, or guacamole).

                                                      For CI feedback, since our CI/CD jobs are just nomad batch jobs, it’s just a nomad run project-dev.nomad command away.

                                                      I.e. we prefer general tools we have to use anyway to solve these problems, instead of specific tools.

                                                      1. 3

                                                        For me and us @ $WORK, the undo button is either ZFS snapshots(exposed as ~/.snapshots) or $EDITOR’s undo functionality.

                                                        That requires me to either:

                                                        • Have a per-source-tree ZFS dataset (possible with delegated administration, but a change from just having one for my home directory and one for my builds which doesn’t get backed up and has sync turned off)
                                                        • Tracking metadata externally about which of my snapshots corresponds to a checkpoint of which repo.

                                                        In contrast, git already does this via a mechanism that is the same one that I use for other things. Vim has persistent undo, which is great for individual files, but when a change spans a dozen files then trying to use vim’s undo to go back to (and compare against) the state from the middle of yesterday afternoon that worked is hard.

                                                        For human feedback, we have a shared user machine we work from or we use other more general purpose tools, like desktop screen sharing(typically tmux, or guacamole).

                                                        That requires everyone that you collaborate with to be in the same company as you (or introduces some exciting security problems for your admin team to have to care about), for your code review to be synchronous. The first is not true for me, the second would be problematic given that I work with people distributed across many time zones. Again, GitHub’s code review doesn’t have those problems.

                                                        For CI feedback, since our CI/CD jobs are just nomad batch jobs, it’s just a nomad run project-dev.nomad command away.

                                                        That’s fine if everyone running your CI has deploy permissions on all of the infrastructure where you do testing.

                                                        I.e. we prefer general tools we have to use anyway to solve these problems, instead of specific tools.

                                                        The tools that you use have a lot of constraints that would prevent me from using them in most of the places where I use git.

                                                        1. 1

                                                          Around CI/CD. For local testing with nomad it can be as simple as download the nomad binary then nomad agent -dev then nomad run <blah.nomad> and you can be off to the races, running CI locally.

                                                          We don’t do that, because @ $WORK, our developers are all in-house and it’s a non-issue, to share resources.

                                                          Just to be clear, I’m not trying to convert you, just for those following along at home.

                                                          Also, within Fossil’s commits, you can totally hide stuff from the timeline, similar to git rebase, using amend

                                                          1. 1

                                                            Thanks for the exchange! It’s interesting seeing the different trade-offs on workflow.

                                                            For those following along, another way, totally within fossil to do undo across large amounts of code change is just generate a sqlite patch file instead of a commit. it’s easy enough: fossil patch create <blah.patch> and to undo: fossil patch apply <blah.patch> The patch file will include by default all uncommitted changes in the repo.

                                                        2. 1

                                                          an undo button that works across files, so once something is working and I want to clean it up, I can always see what I’ve changed and broken during cleanup.

                                                          The staging area is underappreciated for this problem. Often when I hit a minor milestone (the tests pass!) I’ll toss everything into staged and then try to make it pretty in unstaged. With a good git UI it’s easy to look at the unstaged hunks in isolation and blow them away if I mess up. Good code gets promoted to the staging area and eventually I get a clean commit.

                                                          …and then I end up with lots of messy commits anyway to accommodate the “humans or CI” cases. :)

                                                        3. 1

                                                          In short, for backing it up or for pushing out multiple commits to create a design sketch.

                                                          1. 1

                                                            The Fossil “Rebase Considered Harmful” document provides a lot of reasons for committing WIP: bisect works better, cherry-picks work better, backouts work better. Read the doc for more: https://www2.fossil-scm.org/home/doc/trunk/www/rebaseharm.md

                                                            Rebase is a hack to work around a weakness in git that doesn’t exist in fossil.

                                                            The Git documentation acknowledges this fact (in so many words) and justifies it by saying “rebasing makes for a cleaner history.” I read that sentence as a tacit admission that the Git history display capabilities are weak and need active assistance from the user to keep things manageable. Surely a better approach is to record the complete ancestry of every check-in but then fix the tool to show a “clean” history in those instances where a simplified display is desirable and edifying, but retain the option to show the real, complete, messy history for cases where detail and accuracy are more important.

                                                            So, another way of thinking about rebase is that it is a kind of merge that intentionally forgets some details in order to not overwhelm the weak history display mechanisms available in Git. Wouldn’t it be better, less error-prone, and easier on users to enhance the history display mechanisms in Git so that rebasing for a clean, linear history became unnecessary?

                                                        4. 5

                                                          Sometimes it’s policy/law. When software starts mucking about with physical things that can kill/maim/demolish lives, stuff has to be kept track of. Think airplane fly by wire systems, etc. Fossil is good for these sorts of things, git could be with lots of policy around using it. Some industries would never allow a git rebase, for any reason.

                                                          • The perspective of Fossil is: Think before you commit. It’s called a commit for a reason.
                                                          • The perspective of Git is, commit every nanosecond and maybe fix the history later.

                                                          Of course history being immutable can be annoying sometimes, but history is messy in every version of history you look at, except perhaps kindergarten level history books :P I’m not a kindergartener anymore, I can handle the real history.

                                                          For me at $WORK, it’s policy.

                                                          1. 6

                                                            Ah, a policy reason certainly makes sense. I work in FinTech, where policy and/or law has not quite caught up to software to burden us with a more deeply ingrained moral responsibility to assure accountability of the software we write.

                                                            • The perspective of Fossil is: Think before you commit. It’s called a commit for a reason.
                                                            • The perspective of Git is, commit every nanosecond and maybe fix the history later.

                                                            Of course history being immutable can be annoying sometimes, but history is messy in every version of history you look at, except perhaps kindergarten level history books :P I’m not a kindergartener anymore, I can handle the real history.

                                                            This is condescending. Human beings make mistakes and storing those mistakes in all cases isn’t always a valuable artifact. Imagine a text editor that disallows text deletions. “You should have thought harder before typing it.” Come on, dude.

                                                            1. 7

                                                              Imagine a text editor that disallows text deletions.

                                                              We call that Blockchain Notepad.

                                                              1. 4

                                                                Thanks, I hate it!

                                                              2. 3

                                                                I had a :P in there :)

                                                                I apologize, but come on, it’s not like your comparison is remotely fair either :)

                                                                Human beings make mistakes and storing those mistakes in all cases isn’t always a valuable artifact.

                                                                I agree. Fossil(and git) both have ways to fix mistakes that are worth cleaning up. Git just has more of them. See “2.7 What you should have done vs. What you actually did” in the OP’s link.

                                                                1. 1

                                                                  One thing I’m seeing about fossil that illuminates things a bit is that it looks like it might be possible to limit what sets of changes you see as a product of querying the change sets. This seems useful - not to reproduce something git-like - but to limit only to the changes that are considered more valuable and final than anything more transient. If that’s the case, I can see the “mess” of fossil being less of a problem, though with the added cost of now needing to be comfortable with querying the changes.

                                                              3. 5

                                                                I’d much rather have cleaned up history than try to bisect around half-finished commits.

                                                                1. 3

                                                                  From a Fossil perspective, half finished commits belong locally or in .patch files to move around(which in Fossil land are sqlite3 files, not diffs). They don’t belong in commits.

                                                                  To be clear I agree with you, bisecting half-finished commits are terrible. Fossil just has a different perspective and workflow than Git when it comes to this stuff.

                                                                  1. 2

                                                                    I imagine that the way this would get handled in fossil land is people making local half commits then redrafting the changes cleanly on another branch and using that as the official commits to release

                                                                  2. 3

                                                                    There’s a series of steps that any change takes as it passes through decreasingly mutable tiers of storage, so to speak:

                                                                    • typing moves things from the programmer’s brain to an editor buffer
                                                                    • saving moves things from an editor buffer to a file
                                                                    • committing moves things from a file to a (local) repo’s history
                                                                    • pushing moves things from a local repo to a (possibly) public one

                                                                    The question is at what level a given change becomes “permanent”. With git it’s really only when you’ve published your history, whereas it sounds like fossil’s approach doesn’t really allow the distinction between the last two and hence that happens on every (local) commit.

                                                                    You could move the point-of-no-undo even earlier and install editor hooks to auto-commit on every save, or save and commit on every keystroke, but I think most people would agree that that would produce an unintelligible useless mess of history, even if it is “a more accurate record of reality” – so even in the fossil approach you’re still looking at a somewhat massaged, curated view of the development history. I think git’s model just makes that curation easier, by allowing you to create “draft” commits and modify them later.

                                                                    1. 2

                                                                      Fossil’s perspective would be, once it’s committed it is immutable, but you can do reporting on it and make it spit out whatever you want. i.e. Fossil really is just a fancy UI and some tooling around a SQLite database. There is basically no end to what one can do when your entire code tree is living in a SQL database.

                                                                      i.e. You don’t change the history, you change the report of history to show the version of reality that is interesting to you today.

                                                                      Fossil even includes an API for it: https://www2.fossil-scm.org/home/doc/trunk/www/json-api/api-query.md Not to mention the built-in querying available for instance in the timeline view

                                                                    2. 3

                                                                      While I disagree with conclusion, I appreciate you taking the time to explain this way of looking at it. The legality angle seems reasonable, (and, ofc, if you have no choice, you have no choice) but digging further I have some questions for you….

                                                                      1. By this line of reasoning, why is the fossil commit the unit of “real history”? Why not every keystroke? I am not just being facetious. Indeed, why not screen record every editing session?
                                                                      2. Given that the fossil commit has been deemed the unit of history, doesn’t this just encourage everyone to big-batch their commits? Indeed, perhaps even use some other mechanism to save ephemeral work while I spend hours, or even days, waiting for my “official work” to be done so that I can create clean history?

                                                                      I’m not a kindergartener anymore, I can handle the real history.

                                                                      This strikes me an almost Orwellian reversal, since I would say: “You (coworker) are not a kindergartner anymore. Don’t make me read your 50 garbage commits like ‘checkin’, ‘try it out’, ‘go back’, etc, when the amount of changes you have merits 3 clean commits. Have the basic professionalism to spend 5-10 minutes to organize and communicate clearly the work you have actually done to your current and future coworkers.” I am no more interested in this “true history” than I am interested in the 5 intermediate drafts of the email memo you just sent out.

                                                                      1. 2

                                                                        Don’t make me read your 50 garbage commits …

                                                                        It sounds like we are no longer discussing Fossil, but a way of using Git where you do not use rebase.

                                                                        Here’s what the Fossil document says:

                                                                        Git puts a lot of emphasis on maintaining a “clean” check-in history. Extraneous and experimental branches by individual developers often never make it into the main repository. Branches may be rebased before being pushed to make it appear as if development had been linear, or “squashed” to make it appear that multiple commits were made as a single commit. There are other history rewriting mechanisms in Git as well. Git strives to record what the development of a project should have looked like had there been no mistakes.

                                                                        Fossil, in contrast, puts more emphasis on recording exactly what happened, including all of the messy errors, dead-ends, experimental branches, and so forth. One might argue that this makes the history of a Fossil project “messy,” but another point of view is that this makes the history “accurate.” In actual practice, the superior reporting tools available in Fossil mean that this incidental mess is not a factor.

                                                                        Like Git, Fossil has an amend command for modifying prior commits, but unlike in Git, this works not by replacing data in the repository, but by adding a correction record to the repository that affects how later Fossil operations present the corrected data. The old information is still there in the repository, it is just overridden from the amendment point forward.

                                                                        My reading is that Fossil permits you to view a “clean” history of changes due to its “superior reporting tools” and the “correction records” added by the amend command. But unlike Git, the original commit history is still recorded if you need to see it.

                                                                        1. 1

                                                                          My reading is that Fossil permits you to view a “clean” history of changes due to its “superior reporting tools” and the “correction records” added by the amend command. But unlike Git, the original commit history is still recorded if you need to see it.

                                                                          Ok that is interesting… I had been assuming that they were dismissing the value of clean history, but it seems they are not, but instead solving the same problem but at a different level in the stack.

                                                                        2. 1

                                                                          By this line of reasoning, why is the fossil commit the unit of “real history”? Why not every keystroke? I am not just being facetious. Indeed, why not screen record every editing session?

                                                                          That’s what Teleport is for. Other tools obviously also do this.

                                                                          More generally, stuff in the commit tree will eventually make it to production and run against real data and possibly hurt people. The stuff that can hurt people needs to be tracked. The ephemeral stuff in between doesn’t much matter. If I was purposefully negligent in my code, no amount of ephemeral work would prove it, there would be some other mechanism in place to prove that (my emails to a co-conspirator maybe, recording me with that evil spy, etc).

                                                                          Given that the fossil commit has been deemed the unit of history, doesn’t this just encourage everyone to big-batch their commits? Indeed, perhaps even use some other mechanism to save ephemeral work while I spend hours, or even days, waiting for my “official work” to be done so that I can create clean history?

                                                                          Why do you need to commit ephemeral work? what is the point?

                                                                          Have the basic professionalism to spend 5-10 minutes to organize and communicate clearly the work you have actually done to your current and future coworkers.”

                                                                          LOL fair point :) But that goes back to the previous comments, what is the purpose of committing ephemeral work? From my perspective there are 2 general reasons:

                                                                          • Show some pointy haired boss you did something today
                                                                          • Share some code in progress with another person to help solve a problem, code review, etc.

                                                                          The 1st, no amount of code commits will solve this, it’s either trust me or come sit next to me and watch me do stuff(or screen record, video record my office, etc). If my boss doesn’t trust me to be useful to the organization, I’m at the wrong organization.

                                                                          The 2nd, is easily solved in a myriad of ways, from desktop/screen sharing, to code collab tools to sharing Fossil patch files around.

                                                                          I truly don’t understand the point of committing half-done work like Git proponents seem to think is an amazing idea. A commit needs to be USEFUL to be committed. Perhaps it’s part of a larger body of work, it’s very common to do that, but then it’s not ephemeral, you are doing a cleanup so you can then implement $FEATURE, that cleanup can happily be it’s own commit, etc.

                                                                          But committing every nanosecond or on every save is just idiotic from my point of view. If you want that sort of thing, just run against a versioned file system. You can do this with ZFS snapshots if you don’t want to run a versioned file system. Git is not a good backup tool.

                                                                          1. 4

                                                                            I think this is fundamentally a workflow difference.

                                                                            Proponents of git, myself included, use committing for many purposes, including these prominent ones:

                                                                            1. A way to save partially complete work so you don’t lose it, or can go back to that point of time in the midst of experimentation.
                                                                            2. A way to share something with a co-worker that will not be part of permanent history or ever merged.

                                                                            The 2nd, is easily solved in a myriad of ways, from desktop/screen sharing, to code collab tools to sharing Fossil patch files around.

                                                                            Yes, I suppose there are other ways to solve the sharing problem. But since we do everything in git anyway and will have a PR in Github anyway, it is very convenient to just commit to share, rather than introduce a new mechanism for sharing.

                                                                            I truly don’t understand the point of committing half-done work like Git proponents seem to think is an amazing idea. A commit needs to be USEFUL to be committed.

                                                                            Sharing code to discuss and backing up milestones of incomplete, experimental are both very useful to me.

                                                                            1. 1

                                                                              I think the disconnect is probably in what we consider “ephemeral.” You seem to think that we’re “idiotically [. . .] committing every nanosecond” (which, seriously, stop phrasing it like this because you’re being an asshole), but in most of my own use cases it’s simply a matter of wanting to preserve the current state of my work until I’ve reached a point where I’m ready to construct what I view as a salient description of the changes. In many cases this means making commits that roughly match the structure I’m after - a sort of design sketch - and maybe these don’t include all of the test changes yet, and I haven’t fully written out a commit message because I haven’t uncovered all the wrinkles that need ironing as I continue the refactor, and I find something later that makes more sense as a commit in the middle because it relates directly to that other block of work, and and and…

                                                                              An example: when I reach the end of the day, I may want to stash what I’m working on or - depending on the amount of work I’ve put in - I may want to push up a WIP commit so that if something happens on my workstation that I don’t lose that work (this is always a real concern for reasons I won’t go into). Maybe that WIP commit doesn’t have tests passing in it, and I and my team try to follow the practice of ensuring that every commit makes a green build, so I don’t want that to be the final version of the commit that eventually makes it into the main branch. The next day I come in, reset my WIP commit and add the test changes I was missing and now make the actual commit I want to eventually see pushed up to the main branch.

                                                                              I don’t know of anybody who thinks saving things in WIPs for untangling later is - as you say - “an amazing idea,” but it’s a natural extension of our existing workflow.

                                                                    3. 6

                                                                      I use both Fossil and Git at work, although we are almost done with moving all the Fossil repos to Git.

                                                                      Fossil is fine, but the immutability is kind of annoying in the long term. The lack of a rebase for local work is a drag.

                                                                      Its biggest problem is tooling. Nothing works with it. It doesn’t integrate with the CI system without a lot of effort, there’s no Bitbucket/Github-like system to use for PRs or code reviews, and it doesn’t integrate with the ticket system. Sure, it contains all those things, but they don’t meet the needs we (and most others, it seems) require.

                                                                      On a personal note, I dislike the clone/open workflow as I’d much rather have the database in the project directory similar to the .git directory. There are other little things I don’t like, but they are mostly because I’m used to Git, despite all its flaws.

                                                                      1. 3

                                                                        I would argue it’s because your perspective around Fossil is wrong when it comes to immutability. Fossil’s perspective is when you commit, it’s literally a commitment, it’s done. Be careful and think about your commits. Practically the only thing we have noticed is occasionally we get ‘oops fixed typo’ type commits.

                                                                        I agree with the clone/open workflow, but it’s that way for a reason, the perspective is, you clone locally once, and you open per branch/feature you want to mess with. So a cd is all you need to switch between branches. Once I figured that out, I didn’t mind the workflow that much, I just have a ~/fossil dir that keeps all my local open projects, and otherwise I mostly ignore that directory.

                                                                        I agree with the tooling problem, though I don’t think it’s quite as bad as you think. There is fossil patch for PR/code review workflows. The only special tooling fossil gives you here is the ability to copy and apply the patch to a remote SSH host. Perhaps that could be changed, but it allows you to develop your own workflow if you care about those sorts of things.

                                                                        I have a totally different perspective than the entire industry around CI/CD. CI/CD is just a specialization of running batch jobs. Since we have to run batch jobs anyway, we just use our existing batch job tooling for CI/CD. For us, that means our CI/CD integration is as simple as a commit hook that runs: nomad run <reponame.nomad> After that our normal nomad tooling handles all of our CI/CD needs, and allows anyone to start a CI/CD run, since it’s all in the repo, there is no magic or special tooling for people to learn. If you have to learn how production works anyway for batch jobs there is no sense in learning a diff. system too.

                                                                        1. 2

                                                                          It’s not just about perspective. I’m firmly in the mutable history camp, because a lot of my work - the vast majority of it, really - is experimenting and research. It’s all about coming up with ideas, sharing them, seeking feedback, and iterating. Most of those will get thrown out the window after a quick proof of concept. I see no point in having those proof of concepts be part of the history. Nor will I spend considerable time and effort documenting, writing tests and whatnot for what is a proof of concept that will get thrown out and rewritten either way, just to make the history usable. I’d rather just rearrange it once the particular branch is being finalised.

                                                                          Immutable history is great when you can afford it, but a huge hindrance when you can’t.

                                                                          With git, both can be accomplished with a little care: no force pushes to any branch. Done.

                                                                          What one does locally is irrelevant. Even with Fossil, you will likely have had local variations before you ended up comitting it. The difference with git is that you can make local snapshots and rearrange them later, using the same tool. With Fossil, you would have to find some other way to store draft work which is not ready to become part of the immutable history.

                                                                          I mean, there’ve been many cases over my career where I was working on a thing that became a single commit in the end, for days, sometimes even weeks. I had cases where that single commit was a single line changed, not a huge amalgamation or anything like that. But it took a lot of iteration to get there. With git, I could commit my drafts, share it with others, and then rewrite it before submitting it upstream. I made use of that history a lot. I rolled back, reverted, partially reverted, looked at things I tried before, and so on. With Fossil, I would have had to find a way to do all that, without comitting the drafts to the immutable history. It would have made no sense to commit them - they weren’t ready. Yet, I still wanted to iterate, I still wanted to easily share with colleagues.

                                                                          1. 3

                                                                            Clearly you and I are going to disagree, but I would argue that Fossil can handle your use-case just fine, albeit very differently than Git would handle it. You have clearly gotten very use to the Git workflow model, and that’s fine. That doesn’t mean the Fossil workflow model is wrong or bad or evil or anything, it’s just different than Git’s, because (I’d argue) it’s coming from a different perspective.

                                                                            Fossil does have ways to store draft work and ship it around, I mentioned two ways in the comment you are replying to, but you either didn’t see them or just chose to ignore them. fossil patch is actually pretty cool, as the patch file is just a sqlite3 file. Easy to ship/move/play with.

                                                                            1. 2

                                                                              I wasn’t saying the Fossil model is bad - it isn’t. It’s just not suitable for every scenario, and I have yet to see what benefit it would have over the mutable model for me. Just because it can handle the scenarios I want doesn’t mean it’s easy, convenient or straightforward to do it. Git can do immutable workflows too, and mutable ones too - it just makes the latter a lot easier, while the former possible if you put in the work.

                                                                              I did not see your comments about fossil patch before, I skipped over that part of your comment, sorry. However, that’s not suitable for my workflow: I don’t need a single patch, I can ferry one around easily, that wouldn’t be a problem. I work with branches, their history important, because I go often go back and revert (fully or partially), I often look back at things I tried before. That is important history during drafting, but completely irrelevant otherwise. Git lets me do dirty things temporarily, and share the refined result. Fossil lets me ferry uncomitted changes around, but that’s so very far from having a branch history. I could build something on it, sure. But git already ships with that feature out of the box, so why would I?

                                                                              I could, of course, fork the repo, and do my draft commits in the fork, and once it reaches a stage where it’s ready to be upstreamed, I can rebuild it on top of the main repo - manually? Or does Fossil have something to help me with that?

                                                                              I’m sure it works in a lot of scenarios, where the desire to commit often & refine is less common than think hard & write only when it’s already refined. It sounds terrible for quick prototyping or proof of concepts (which are a huge part of my work) within an existing project.

                                                                              1. 2

                                                                                Fossil really is just a fancy UI and some tooling around a SQLite database. There is basically no end to what one can do when your entire code tree is living in a SQL database. You don’t need 100k confusing git commands, when you literally can type sqlite3 <blah.fossil> and do literally anything you want. If fossil will understand it for you after is of course an exercise left to the SQL writer. :)

                                                                                That is important history during drafting, but completely irrelevant otherwise.

                                                                                Fossil has a different perspective here. All history is important.

                                                                                I think the big difference here is, Fossil’s UI and query tools are vastly more functional than Git’s. Literally an entire SQL implementation. Meaning you can hide/ignore loads of stuff from the history, so that in practice most of this ‘irrelevant history’ can be hidden from view the vast majority of the time.

                                                                                I could, of course, fork the repo, and do my draft commits in the fork, and once it reaches a stage where it’s ready to be upstreamed, I can rebuild it on top of the main repo - manually? Or does Fossil have something to help me with that?

                                                                                Yes, see: https://www2.fossil-scm.org/home/doc/trunk/www/branching.wiki

                                                                                No need to fork, a branch should work just fine.

                                                                                1. 2

                                                                                  Fossil really is just a fancy UI and some tooling around a SQLite database.

                                                                                  Similarly, git is just an UI over an object store. You can go and muck with the files themselves, there are libraries that help you do that. If git will understand it for you after, is an exercise left for whoever mucks in the internals. ;)

                                                                                  Fossil has a different perspective here. All history is important.

                                                                                  And that is my major gripe. I do not believe that all history is important.

                                                                                  Meaning you can hide/ignore loads of stuff from the history, so that in practice most of this ‘irrelevant history’ can be hidden from view the vast majority of the time.

                                                                                  It still takes up space, and it still takes effort to even figure out what to ignore. With git, it’s easy: it simply isn’t there.

                                                                                  No need to fork, a branch should work just fine.

                                                                                  According to the document, a branch is just a named, intentional fork. From what I can tell, the history of the branch is still immutable, so if I want to submit it upstream, I would still need to manually rebuild it first. Fossil maintains a single DAG for the entire repo (so the linked doc says), so if I wanted to clean things up before I submit it upstream, I’d need to rebuild by hand. With git, I can rebase and rewrite history to clean it up.

                                                                                  1. 2

                                                                                    I do not believe that all history is important.

                                                                                    Seconded.

                                                                                    We do not have to remember everything we do.

                                                                              2. 1

                                                                                Can you explain a little bit more how things like code reviews work? I’m not skeptical that they can’t be done in fossil, it’s just that the workflow is so different from what I’m used to.

                                                                                1. 2

                                                                                  I am by no means a Fossil expert, but I’ll give you my perspective. Fossil handles moving the code back and forth, the rest is up to you.

                                                                                  I work on a new feature and am ready to commit, but I want Tootie to look it over(code review). If we have a shared machine somewhere with SSH and fossil on it, I can use fossil patch push server:/path/to/checkout and push my patch to some copy for her to look at. If not I can fossil patch create <feature.patch> and then send her the .patch file(which is just a sqlite3 DB file) via any method.

                                                                                  She does her review and we talk about it, either in Fossil Forums or Chat, or email, irc, xmpp, whatever. Or she can hack on the code directly and send a new .patch file back to me to play with.

                                                                                  Whenever we agree it’s good to go, either one of us can commit it(assuming we both have commit rights). See the fossil patch docs.

                                                                        2. 1

                                                                          What do you mean of “the same data structure as git”, you know Fossil is using SQLite? I don’t know what the current Git data structure is, but from my experience with it, it is much more complicated to do something with compared to a SQL database.

                                                                          1. 2

                                                                            From the link under heading 2.3:

                                                                            The baseline data structures for Fossil and Git are the same, modulo formatting details. Both systems manage a directed acyclic graph (DAG) of Merkle tree structured check-in objects. Check-ins are identified by a cryptographic hash of the check-in contents, and each check-in refers to its parent via the parent’s hash.

                                                                            1. 1

                                                                              A merkle tree of commits containing the file contents.

                                                                            2. 1

                                                                              I’ve been using Fossil for my personal projects since summer 2020.

                                                                              The main advantages I see compared to git is that it is fairly easy to backup/move to a new server (the repository is just a single SQLite database and not a folder of a custom key/value format), as well as to give other contributors commit access (no shell access required).

                                                                              Beside this, I’m also more inclined to their philosophy of being immutable, as I would otherwise spent way too much time making my commits looks nice.

                                                                            1. 3

                                                                              I can’t flag this as spam due to some CSS problem, but this is spam. The pldb.com domain has already been banned and this is a brazen attempt to get around it.

                                                                              1. 1

                                                                                Interesting! I didn’t know PLDB.com domain has been banned from Lobsters. Thank you for the information.

                                                                                I’m not sure if it makes sense to ban a website that is public domain, open source, ad free, cookie free, tracker free, and that you and anyone can git clone https://github.com/breck7/pldb and even host on your own local server or your own mirror https://pldb.com/pages/mirrors.html.

                                                                                Because it may be so hard to ban (it would be like stamping out an idea by burning books), given the above, perhaps the mods should consider building some sort of UP/DOWN voting system, to deal with this huge spam problem, which by my count has gotten as high as gulp, 2 submissions per day?!

                                                                              1. 2

                                                                                Ok, so I’m super surprised that clang is doing this as the -ffast-math docs (https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math) do not list any changes to the way denormals are handle, nor in fact any change in runtime behavior - everything is compile time assumptions about fp math behaving like infinite precision math, etc.

                                                                                That the clang docs explicitly enumerate the additional fp flags fast-math implies, and does not include the separate -fdenormal-fp-math option makes it even weird.

                                                                                Finally I agree with the author that it is bananas that a shared library thinks that it is reasonable to change global cpu state.

                                                                                1. 7

                                                                                  The documentation is probably accurate, but the setting of the CPU flags is coming from the system startup code, not the compiler directly.

                                                                                  On my Debian Bullseye machine, when I build a trivial shared object using the command

                                                                                  gcc -fpic -shared -o t.so t.c
                                                                                  

                                                                                  it links with /usr/lib/gcc/x86_64-linux-gnu/10/crtfastmath.o. This is the file with the set_fast_math function that does the CPU flag setting. If you build with clang it will link with the same file. This happens when -ffast-math is in effect.

                                                                                  I tried with -rtlib=compiler-rt, -stdlib=libc and -fuse-ld=lld and all combinations link to that file when -ffast-math is turned on. I haven’t tinkered enough to know how to avoid linking with it, unless you write your own and insert it in the link at the correct place.

                                                                                  Incidentally, here’s the offending code in GCC (actually, libgcc). It’s been around for a long time.

                                                                                1. 11

                                                                                  This post is a rambling mess and I recommend you just stay away from it.

                                                                                  1. 3

                                                                                    I didn’t listen to you and I’m sorry I didn’t.

                                                                                  1. 8

                                                                                    but since I still wanted to maintain “clean code”, I decided to make a macro instead of the function

                                                                                    What compiler are you using that doesn’t have an always-inline attribute that you can stick on a function to get the same overhead as a macro, without the ugliness? For that matter, what compiler doesn’t inline a function that’s likely to be lowered to six instructions?

                                                                                    shortStatus.faults |= FAULT_BIT; longStatus.faults = shortStatus.faults; …but from looking at the PIC24 assembly code, that’s much larger

                                                                                    I presume that the status here is that these globals (MMIO objects?) are volatile and so you can’t keep an intermediate in a temporary. The following would likely be smaller:

                                                                                    int tmp = shortStatus.faults | FAULT_BIT;
                                                                                    shortStatus.faults = tmp;
                                                                                    longStatus.faults = tmp;
                                                                                    

                                                                                    But, I was quickly reminded that the PIC architecture doesn’t support passing constant string data due to “reasons”. (Harvard architecture, for those who know.)

                                                                                    That is not a sufficient reason. According to the article, the following works:

                                                                                    const char *msg = "This is my message";
                                                                                    LCDWriteDataString (0, 0, msg);
                                                                                    

                                                                                    But this doesn’t:

                                                                                    LCDWriteDataString (0, 0, "This is my message.");
                                                                                    

                                                                                    This sounds very odd because the assignment to the temporary shouldn’t affect code generation at all. I suspect that this is a compiler bug, not an artefact of the target. My guess, from the following line, is that the code memory is ROM, the data memory is RAM, and they are in separate address spaces. In addition, the compiler is not fully C compliant and so uses a char* that is not large enough to store a pointer to any object (as required by the spec). Generally, systems like this provide an address-space attribute. You would be able to pass a string as a function parameter if you annotated the parameter to specify the address space as the ROM segment.

                                                                                    The above routine maintains a static character buffer of 3 bytes. Two for the HEX digits, and the third for a NIL terminator (0). I chose to do it this way rather than having the user pass in a buffer pointer since the more parameters you pass

                                                                                    Again, an always-inline function would solve this problem.

                                                                                    It sounds as if the compiler that the author is using is absolutely terrible. I’ve written a generic C++ format-string implementation that takes the format sting as a template parameter and does formatting and clang happily lowers it to something equivalent to this custom implementation. There was a PIC back end for LLVM a while ago, I’ve no idea what it’s status is, but in general if you have to fight your compiler this much then you should consider getting a better compiler. The kind of optimisations required here to generate code this good are the kind that you learn in an undergraduate compiler course. Just inlining and common subexpression elimination would have been sufficient.

                                                                                    TL;DR: If you can make your code better by applying a trivial transform that doesn’t rely on any extrinsic knowledge, then your compiler should be able to make everyone’s code better by either applying the same transform everywhere or by applying the transform where instructed by annotations.

                                                                                    1. 5

                                                                                      What compiler are you using…

                                                                                      Buried in the article:

                                                                                      …using the CCS compiler tools

                                                                                      The CCS compiler is almost C89/C90 compliant and if you check out the manual (p. 147) there is an #inline preprocessor directive to mark a function as inline. Whether it works in this case, I don’t know. It sounds like it should, but these old, embedded target compilers can be odd beasts.

                                                                                      It’s also possible the author doesn’t know about #inline (or won’t use it) because it’s not in the standard. But it does seem like it should work in this case.

                                                                                      And having to pass non-constant strings doesn’t make sense to me, unless the compiler is doing something very strange about memory placement and pointer types, as you mention.

                                                                                      1. 3

                                                                                        I’ve never used a PIC24, but there are definitely architectures where you have separate “load from ROM” and “load from RAM” instructions, which both take a word-sized pointer… and this is sometimes mapped into a language with C-like syntax by having (const char *)0x24 and (char *)0x24 point to different memory.

                                                                                        (The alternative being to keep a tag byte for each pointer, telling you to which memory space it points. Which lets you use actual C, but which does not map to the underlying hardware very efficiently.)

                                                                                        1. 1

                                                                                          And having to pass non-constant strings doesn’t make sense to me, unless the compiler is doing something very strange about memory placement and pointer types, as you mention.

                                                                                          I don’t know about the PIC architecture specifically, but on a lot of Harvard architecture systems you have different pointer sizes for the different address spaces. My guess is that PIC has 24-bit ROM pointers and 16-bit RAM pointers and places code and constants in ROM. Taking the address of a constant string gives a 24-bit pointer but, for some reason, they’ve decided that char* is a 16-bit pointer.

                                                                                          The manual (page 44) talks about a rom qualifier that forces data to be placed in ROM and talks about rom pointers, so I believe the correct fix here would simply be to add the rom qualifier to the const char* parameter and then you’d be able to pass constant strings (but only constant strings) as arguments to the function.

                                                                                          I was a bit surprised that printf in their examples can take a constant string given this blog post, but it appears (page 52) as if they support overloaded functions and so there’s a version of printf that takes a const char* and none that takes a rom const char *. Interestingly, only the ROM version is allowed to actually be a format string, which makes me suspect that the compiler is already generating a specialised version of the code for printf, but not for sprintf, motivating this blog post to start with.

                                                                                          The fact that the language provides overloading is very interesting because it may mean that you can write a C++-style formatting implementation, though the lack of a tuple type or C11’s _Generic may mean that it isn’t possible.

                                                                                      1. 26

                                                                                        I’ll go the other way: it is absurd to me that developers repeatedly refuse to attempt to make better estimates, seemingly as a cultural thing.

                                                                                        Devs seem to want this magical fantasy land where they get to tinker with software and get paid six figures and not have to commit to any particular deadline and not have to sully themselves with even trying to make informed guesses about how long something should take. It is absurd.

                                                                                        Here’s a good starting point: “is your current ticket going to take more or less than a year”? As the old joke goes, “….if you answer, we already established that you’re an estimator–now we are just haggling over price.”

                                                                                        1. 22

                                                                                          it is absurd to me that developers repeatedly refuse to attempt to make better estimates, seemingly as a cultural thing.

                                                                                          It is equally absurd to me that people refuse to attempt to spontaneously levitate better, seemingly as a cultural thing.

                                                                                          Estimation requires that the future be like the past. In manufacturing this is described as the process being ‘in control’ so that the normal sources of variation are known and control plots an be drawn without them being a work of fiction. For many things in software we can get certain tasks in control. It is possible to get a lot of the work in software under control, but if you don’t do that work you can’t expect to be able to estimate it. And there is always a big pile of stuff that isn’t under control because it wasn’t foreseen or because it is a rare task.

                                                                                          1. 14

                                                                                            Estimation requires that the future be like the past. In manufacturing this is described as the process being ‘in control’ so that the normal sources of variation are known and control plots an be drawn without them being a work of fiction. For many things in software we can get certain tasks in control. It is possible to get a lot of the work in software under control, but if you don’t do that work you can’t expect to be able to estimate it. And there is always a big pile of stuff that isn’t under control because it wasn’t foreseen or because it is a rare task.

                                                                                            I dunno, there’s a lot of stuff in construction and traditional engineering that’s similarly unforeseen, but they seem to be (somewhat) better at estimating that we are. I wonder if it’s more that we don’t have good techniques or practices. My analogy is formal methods: lots of people told me that up-front design was literally impossible, and I thought that too until I discovered the techniques that make it both possible and economical.

                                                                                            1. 10

                                                                                              My experience in a “boring” branch of EE (instrumentation engineering, specifically, that’s as close to bean counting as you can get…) suggests that poor practices are very much a cultural thing. However, I think poor practices are neatly divvied up between development and management. Software engineering management practices need a major revamp at least as much as software development practices do.

                                                                                              Software engineering managers routinely eschew the management of requirement gathering, synthesis and dissemination, engineering skill building, or process analysis. Much to the embarrassment (and grief) of their organisations, a lot of them do it because they lack the knowledge and skills required for them in the first place. Many eschew these things entirely.

                                                                                              And when they’re eschewed, they’re often not eschewed through sheer incompetence, but by company policy. For example, the software industry is certainly not the only one that has to deal with changing requirements. However, it is, to my knowledge, the only one that’s developed a whole institutional framework out of not providing requirements, and trickling them, one at a time, over a lengthy period of time. “Other” (as in, EE) engineering managers get that even a provisory understanding of provisory requirements is necessary before making any estimates, and that what you choose early on limits what you can do later on to some degree. Of course the estimates they get are better – with all the early stage trade-offs that involves.

                                                                                              Edit: I had a cool story about it, but I don’t think I can obfuscate the details enough to make it untraceable so I decided against posting it. But the core of it is that “lack of requirements” and “shifting requirements” just scratch the surface of how poorly requirements are treated by the software industry. “Requirements gathering” is just the most basic aspect: in many fields of engineering, it’s engineering management 101 to ensure not just that a list of requirements exist, but also that they’re analysed, that everyone on the team understands them and what implications they have, that, if any requirements are missing and are replaced with best guesses, everyone up the chain understands what they’re committing to and so on. Software engineering management barely recognizes that these things exist.

                                                                                              Same goes for e.g. engineering skills development. Top-tier semiconductor engineering companies have pretty detailed plans for how to ensure that, when some technology that’s critical for their strategy will become available some months (or years) from now, their engineers will receive the proper training for it, that it will be integrated in their existing processes and tooling, that knowledge and skills will continue to be disseminated as that technology evolves and so on. Meanwhile, the pinnacle of growing software engineers is time management corporate trainings and workshops whose only considerable advantage over a series of Youtube lectures is a company-paid lunch.

                                                                                              1. 7

                                                                                                I feel like construction is probably not a great counterexample since everybody has anecdotes about a massive public-works infrastructure project going way over schedule/budget, often by years and billions of dollars, or about small private projects – remodeling a kitchen/bathroom, building a new patio – going through similarly frustrating overages of time and budget. In fact, contractors who do that sort of work are sort of notorious for being overcommitted, which suggests poor planning/estimation.

                                                                                                My own experience in software is that it’s most useful to break things down into knowns and unknowns – there are things I’ve done enough times over my career that I can give you very accurate estimates of how long they’ll take to build, but there are also things that I’ve either not done enough, or that involve new variations/twists I’ll have to research, that it’s much harder to be precise up-front about the amount of time they’ll need. This piece says it better than I can.

                                                                                                1. 2

                                                                                                  In fact, contractors who do that sort of work are sort of notorious for being overcommitted, which suggests poor planning/estimation.

                                                                                                  This gets at one of the messy things about estimates: how others see them. In the case of construction, it is usually in a situation where there is a competition and the low bid is the most appealling. That’s a slightly different beast than an estimate someone doesn’t want to hear.

                                                                                              2. 4

                                                                                                Estimation requires that the future be like the past.

                                                                                                This is false. Good, repeatable, rigorous estimation is certainly aided in such cases, but the act of estimating does not require that–Crazy Alex up on the mount always says that tasks take less than a calendar year, and has a 99.999% success rate for any task put before them. Many software engineers I know will refuse to provide even a bad, arbitrary estimate unless pressed.

                                                                                                And there is always a big pile of stuff that isn’t under control because it wasn’t foreseen or because it is a rare task.

                                                                                                This hasn’t been my experience, because usually the engineers have always forseen it (perhaps the one upside of kvetching about technical debt) or there are so genuinely rare tasks. Integrating with an API isn’t a rare task, handling copy changes isn’t a rare task, making CI faster by looking for redundant steps isn’t a rare task–these are all things that are normal and expected in the course of one’s career,

                                                                                                I think we collectively harm our profession by pretending that there is no significant difference in frequency between the occurrences of boring glue/plumbing work and genuinely hard engineering.

                                                                                                1. 4

                                                                                                  Minor addendum:

                                                                                                  The real issue with this approach isn’t the grizzled veteran of a dozen projects who refuses to give an estimate because of their observations of how management at their company treats those estimates or who has seen many projects derailed by acts of Vendor–that person’s reluctance is understandable, and I trust that if pressed and managed properly they’d at least come up with something.

                                                                                                  The problem is all of the brand-new folks to the profession who are hearing “you never give estimates”, “estimates are impossible”, etc. They blindly follow that culture and shortchange themselves, their teams, and their customers.

                                                                                                  1. 1

                                                                                                    the grizzled veteran of a dozen projects who refuses to give an estimate because of their observations of how management at their company treats those estimates

                                                                                                    I’d say even that veteran is being silly. They could always take their actual estimate and double it or whatever they see fit to turn it into an upper bound estimation if management is going to take the estimation and turn it into a deadline.

                                                                                                  2. 3

                                                                                                    Many software engineers I know will refuse to provide even a bad, arbitrary estimate unless pressed.

                                                                                                    There’s usually an underlying disfunction hiding here. When a developer is held to bad estimates, they lose the psychological safety and trust that comes from such things and are wary to try this again.

                                                                                                    1. 3

                                                                                                      Agreed, but the weird thing is seeing this in engineers too early in their careers (bluntly: fresh out of college, first/second job types) to be reasonably exhibiting this pathology. The apocryphal monkeys, firehose, and banana come to mind.

                                                                                                  3. 3

                                                                                                    Estimation requires that the future be like the past.

                                                                                                    Going to second the dissent to this. I think this is statement is incorrect.

                                                                                                    I’ve been able to estimate some large tasks with reasonable accuracy over the years, despite many unknowns. In one case I estimated a task (porting a compiler to a new backend where I didn’t know the codebase) at eight months and was almost dead-on accurate.

                                                                                                    It isn’t magic. You can spend a couple of hours breaking down a task, analyzing it, possibly reverse-engineering it at a high level, probably reading some documentation, and there’s a good chance you will find patterns and situations that have come up before. You can judge your experience with them and go from there.

                                                                                                    Estimates don’t have to be precise. The main complaint many people have is being held to them despite the fudge factor involved. In my estimates I always qualifiy it with the confidence I have in it based on my knowledge of the elements involved, and explain my reasoning. Even at a high level, being able to say “This will take weeks” to “This will take months” is useful.

                                                                                                    1. 1

                                                                                                      I wanted to add that the people who have done this also know that each time they did the thing, it was with a new version of the framework/library/whatever was being used at the time, and each time they ran into different walls, so they know that they can’t estimate correctly. And while “8 months” is probably a good-enough estimate sometime, it is not always so, usually you have to give an estimate on something that takes between 2 days and 3 weeks. The article stated something like that, most of this stuff comes from the “agile” projects. And in my experience, the estimation problem is not with rough estimations and milestones that are measured in months and years (which are imprecise, but can work, in my experience), but the gritty everyday of scrum refinement meetings.

                                                                                                      1. 2

                                                                                                        And in my experience, the estimation problem is not with rough estimations and milestones that are measured in months and years (which are imprecise, but can work, in my experience), but the gritty everyday of scrum refinement meetings.

                                                                                                        I expect this is true. The problem, then, sounds like “Agile” and Scrum.

                                                                                                        I am lucky not to have ever had to do either one of them in any “serious” way, so perhaps that’s why I don’t think doing estimates are a bad thing.

                                                                                                  4. 13

                                                                                                    I don’t think it’s a cultural thing. Given the abysmal track record of estimate I have observed in 15 year of career, whether it be by me or other, I would say it’s more of a resignation and a cry for the madness to stop. All I can use to generate and estimate is a belief, a feeling, based on very little concrete, that the date make sense.

                                                                                                    I have seen that belief been wrong so many many time.

                                                                                                    Even with your example of one year, I have seen it wrong. Yes, a project that the dev thought could be done in one month can balloon to a few years once we hit something unknown. I have seen many one year project not be done after ten years, yes ten time the estimate.

                                                                                                    Your comment say that programmer are late because of a moral failing. That if they would just « man up », they would make good estimate.

                                                                                                    well, no. Just… no.

                                                                                                    After those mountain pile of evidence we have accumulated over half a century, we cannot say that anymore. Dev are just asked for the impossible. Their ability to enunciate a number is completely orthogonal to their ability to make that number accurate.

                                                                                                    Also, dev salary come from their competence In figuring how complexe system should be put together. Those salary were never asked for a talent to estimate. If they were, employer could have refused and replaced them easily with some homeless person, who would have been just as accurate. But they did not. Because they could not.

                                                                                                    I don’t know of any employer who have found those accurate estimator yet.

                                                                                                    Do you?

                                                                                                    1. 11

                                                                                                      I think what’s absurd is asking people to give an answer to long it would take to build a building.

                                                                                                      It’s a three-bedroom house in X city, but no plans are required, nor is the street it’s on. Is this on a hill? What does the drainage look like?

                                                                                                      Even if an exact lat/long is given, you don’t automatically know what utilities are available without research. You don’t know what permits are required without research. You don’t know the level of the water table or the type of soil without research.

                                                                                                      And you haven’t even started building.

                                                                                                      Writing software is an exercise in building new things under new constraints. Estimates are basically throwing a dart at a wall. The minimum scope is generally known. The maximum is vague, if it’s knowable at all.

                                                                                                      1. 7

                                                                                                        Here are some architects discussing how to estimate project time. So I don’t think it’s only developers.

                                                                                                        Processes that take an easily predictable time in software development (compiling, deploying) take up a minority of most developers time. We can’t use them to figure out the time like for example building construction could, as time for concrete to set, or time to place 100 bricks can be estimated a lot easier, because exactly the same task has already been done millions of times, and has been well characterized.

                                                                                                        And even then, infrastructure projects encounter delays, because sometimes not everything gets accounted for, not every environment variable has been measured beforehand, and some variables have changed since.

                                                                                                        Maybe programming is a bit more unique, because since of the massive possibility for re-usability of our work, every time it is unique, which makes characterization even harder.

                                                                                                        1. 5

                                                                                                          Basically this. I don’t enjoy estimating or claim to have any secret knowledge that makes me better at it. However, I also recognise the need to plan work, and communicate dates to stakeholders.

                                                                                                          Where this becomes a problem is when people don’t recognise that:

                                                                                                          a) estimates are not sacred, and/or

                                                                                                          b) plans are necessary, but rarely end up perfectly matching reality

                                                                                                          If we can all accept that we’re working with imperfect information - and communicate when that breaks down - then it’s an inconvenience at worst, and a useful tool at best.

                                                                                                          1. 4

                                                                                                            Bingo. The old saw “Plans are useless, planning is indispensable” holds true.

                                                                                                            Communicating when the plans break down, or when significant new information has become known, is super important–and I’ll freely admit many orgs screw up that part really badly in how they react.

                                                                                                          2. 2

                                                                                                            I don’t disagree with the point that there’s a cultural aspect to this, but the real problem starts upstream. I think a huge percentage of the ills of modern software development are actually the ills of modern requirements gathering.

                                                                                                            Agile has made a badge of honor out of not pressing stakeholders to think rigorously.

                                                                                                            I love building software but if there’s one thing that’s going to burn me out on working in the industry, it’s having to repeatedly debug requirements and point out situations the product owners didn’t consider. I don’t think it should take a degree in CS to notice that if you, say, make a given input field optional, you can’t just assume it is always available for a mandatory calculation later on.

                                                                                                          1. 2

                                                                                                            The compiler is gcc itself…

                                                                                                            Not to be pedantic, but gcc is actually the driver. It is mostly option processing. The C compiler is cc1; the C++ compiler is cc1plus. These are found in the GCC installation directory, which you can find with gcc --print-search-dirs in the “programs” section. The driver’s job is to choose what tool to run (compiler, assembler, or linker) and put all the options together for the tool based on what the user provides combined with the option logic of specs.

                                                                                                            You can see what options and environment variables are passed to them when you run gcc -v.

                                                                                                            1. 2

                                                                                                              That’s true, I explicitly mention that in future posts, but in this one I didn’t mention that specifically.

                                                                                                              EDIT: What I meant by that specific sentence you mention is the code that makes the compilation is inside the GCC codebase, but the other parts are not included and are part of a different project.

                                                                                                            1. 16

                                                                                                              It’s really hard to take an article like this seriously.

                                                                                                              The opening paragraph:

                                                                                                              This article deals with the use of bool in C++. Should we use it or not? That is the question we will try to answer here. However, this is more of an open discussion than a coding rule.

                                                                                                              So we are having an “open discussion” in an article whose title is definitive, denying the very idea of a discussion. Gotcha.

                                                                                                              Then, if you continue, the “discussion” is laughably simplistic and narrow. It trades Booleans for types with a design that is most generously described as questionable. The problem at the core is understanding the problem domain. If a function like shouldBuyHouse is taking parameters to describe all the variations, then trading Booleans for types isn’t going to solve much unless your domain is rudimentary, in which case Booleans are probably just fine.

                                                                                                              1. 2

                                                                                                                It’s really a question on the use of booleans in function signatures, not in general.

                                                                                                                If a function like shouldBuyHouse is taking parameters to describe all the variations, then trading Booleans for types isn’t going to solve much unless your domain is rudimentary, in which case Booleans are probably just fine.

                                                                                                                It’s definitely better if calling a function like shouldByHouse requires identifiers named hasPool/noPool versus positional true/false params. That is, shouldBuyHouse(hasPool, badLights) is definitely better than shouldBuyHouse(true, false). Right? No?

                                                                                                                1. 3

                                                                                                                  It’s definitely better if the caller is passing a constant, as in your example.

                                                                                                                  It gets awkward otherwise:

                                                                                                                  shouldBuyHouse(buyerCanSwim == canSwim ? hasPool : doesntHavePool,
                                                                                                                      buyerIsBlind ? badLights : goodLights)
                                                                                                                  

                                                                                                                  I love C++ enum classes, but the drawback is they have no implicit conversions to anything…

                                                                                                                  Another way to look at the problem described here is that it’s a lack of parameter naming at the call site. Booleans are much clearer in shouldBuyHouse(hasPool: true, badLights: false). Right?

                                                                                                                  1. 2

                                                                                                                    I agree 100% - the lack of named arguments in c++ is mostly why we resort to using enum classes to represent boolean values. Unfortunately this trick only works for booleans and not so much for strings or other types, which is why we often resort to the builder pattern or similar idioms to simulate named arguments.

                                                                                                                    1. 1

                                                                                                                      Well, you probably wouldn’t express the mapping of buyerCanSwim to hasPool, or buyerIsBlind to whichLights, inline with the calling expression.

                                                                                                                      poolRequirement = buyerCanSwim ? hasPool : doesntHavePool
                                                                                                                      lightRequirement = buyerIsBlind ? badLights : goodLights
                                                                                                                      purchaseDecision = shouldBuyHouse(poolRequirement, lightRequirement)
                                                                                                                      

                                                                                                                      Named parameters have appeal, but they tend to go hand-in-hand with optionality, which is a huge source of risk, IME far more costly than the benefits delivered by the feature. If you could have named parameters without the option of leaving any out, then I’d agree that’s a good solution, except that it still allows callers to call shouldBuyHouse(true, false) which is exactly the thing we’re trying to prevent, here, by construction. So I dunno. I wouldn’t put them in my language.

                                                                                                                      1. 2

                                                                                                                        I think Swift’s approach is quite interesting: https://docs.swift.org/swift-book/LanguageGuide/Functions.html

                                                                                                                        Parameter names are encouraged by the syntax and non-optional for the caller, and must be provided in definition order. There’s a syntax to say “caller doesn’t need to provide a name here” but the caller needs to provide the argument names in basic looking signatures like shouldBuyHouse(hasPool: bool, badLights: bool) -> bool.

                                                                                                                        Swift does have default parameters though, which are as bad or worse than optional parameters - but at least they need to be trailing, and order is guaranteed.

                                                                                                                    2. 2

                                                                                                                      When it’s a function with two parameters backing an uncompelling example, then I argue it still mostly doesn’t matter, and if you want those identifiers could be globals or even macros, if you’re using C.

                                                                                                                      I’m not advocating for Booleans as arguments in general, I’m just asking for better writing. This is article is not worth anyone’s time.

                                                                                                                      1. 3

                                                                                                                        If the two parameters you mention are both booleans, then for readability it definitely matters whether you use a bool or an enum. The tradeoff is some extra work for the enum, and it’s reasonable to argue whether (or not) the extra work is worthwhile.

                                                                                                                        One bonus the enum gives you is you can more easily replace it with a policy object.

                                                                                                                  1. 19

                                                                                                                    This implementation is not nearly pure GNU Make enough for me. :)

                                                                                                                    Here’s one that is pure Make. Some of it is cribbed from The GNU Make Book and not all the definitions are necessary. Numbers are represented by a list of xs. So 5 would be the string x x x x x.

                                                                                                                    It counts down from 100 instead of up. I don’t really care.

                                                                                                                    _pow2 = $(if $1,$(foreach a,x x,$(call _pow2,$(wordlist 2,$(words $1),$1))),x x)
                                                                                                                    _all := $(call _pow2,1 2 3 4 5 6 7 8) 
                                                                                                                    num = $(words $1)
                                                                                                                    val = $(wordlist 1,$1,$(_all))
                                                                                                                    incr = x $1
                                                                                                                    decr = $(wordlist 2,$(words $1),$1)
                                                                                                                    
                                                                                                                    max = $(subst xx,x,$(join $1,$2))
                                                                                                                    min = $(subst xx,x,$(filter xx,$(join $1,$2)))
                                                                                                                    
                                                                                                                    eq = $(filter $(words $1),$(words $2))
                                                                                                                    ne = $(filter-out $(words $1),$(words $2))
                                                                                                                    gt = $(filter-out $(words $2),$(words $(call max,$1,$2)))
                                                                                                                    gte = $(call gt,$1,$2)$(call eq,$1,$2)
                                                                                                                    lt = $(filter-out $(words $1),$(words $(call max,$1,$2)))
                                                                                                                    lte = $(call lt,$1,$2)$(call eq,$1,$2)
                                                                                                                    
                                                                                                                    add = $1 $2
                                                                                                                    subtract = $(if $(call gte,$1,$2),$(filter-out xx,$(join $1,$2)),$(warning Underflow))
                                                                                                                    multiply = $(foreach a,$1,$2)
                                                                                                                    divide = $(if $(call gte,$1,$2),x $(call divide,$(call subtract,$1,$2),$2),)
                                                                                                                    mod = $(if $(call gte,$1,$2),$(call mod,$(call subtract,$1,$2),$2),$1)
                                                                                                                    
                                                                                                                    fizz = $(call eq,$(call val,0),$(call mod,$1,$(call val,3)))
                                                                                                                    buzz = $(call eq,$(call val,0),$(call mod,$1,$(call val,5)))
                                                                                                                    fizzbuzz = $(and $(call fizz,$1),$(call buzz,$1))
                                                                                                                    
                                                                                                                    fbcheck = $(if $(call fizzbuzz,$1),$(info FizzBuzz),\
                                                                                                                                $(if $(call fizz,$1),$(info Fizz),\
                                                                                                                                   $(if $(call buzz,$1),$(info Buzz),\
                                                                                                                                       $(info $(call num,$1)))))
                                                                                                                    
                                                                                                                    loop = $(if $1,$(call fbcheck,$1)$(call loop,$(call decr,$1)),)
                                                                                                                    
                                                                                                                    all: ; @echo $(call loop,$(call val,100))
                                                                                                                    
                                                                                                                    1. 7

                                                                                                                      This implementation is not nearly pure GNU Make enough for me. :)

                                                                                                                      That’s the spirit :-) I saw a blog post about doing this kind of arithmetic in make but didn’t want to go this far down the rabbit hole. I’m glad you did though.

                                                                                                                      1. 4

                                                                                                                        Comments and articles like these are why I love lobste.rs :D

                                                                                                                        1. 3

                                                                                                                          Wow. Some things people were not meant to know.

                                                                                                                          This note implies GNU make is Turing complete.

                                                                                                                          https://okmij.org/ftp/Computation/#Makefile-functional

                                                                                                                        1. 16

                                                                                                                          This is an excellent resource! I worked on a feed reader from 2003-2007, and broken feeds were a constant annoyance. A lot of this seemed to be caused by generating the feed using the same template engine as the HTML but not taking account of the fact that it’s supposed to be XML

                                                                                                                          I hope the situation is better now, but the major mistakes I saw then were:

                                                                                                                          • Invalid XML, probably caused by sloppy code generating it. People get used to sloppy HTML because browsers are forgiving, but XML is stricter and doesn’t allow improper nesting or unquoted attributes.
                                                                                                                          • HTML content embedded unquoted in the XML. This can be done legally, but the content has to be valid XHTML, else it breaks the feed. If in doubt, wrap CDATA around your HTML.
                                                                                                                          • Incorrectly escaped text. It’s not hard to XML-escape text, but people managed to screw it up. Get it wrong one way and it breaks the XML; or you can double-escape and then users will see garbage like “&quot;” in titles and content.
                                                                                                                          • Bad text encoding. Not declaring the encoding and making us guess! Stating one encoding but using another! An especially “fun” prank was to use UTF-8 for most of the feed but have the content be something else like ISO-8859.
                                                                                                                          • Badly-formatted dates. This was a whole subcategory … using the wrong date format, or localized month names, or omitting the time zone, or other more creative mistakes.
                                                                                                                          • Not using entry UUIDs and then changing the article URLs. Caused lots of complaints like “the reader marked all the articles unread again!”
                                                                                                                          • Serving the feed as dynamic content without a Last-Modified or Etag header. Not technically a mistake, but hurts performance on both sides due to extra bandwidth and the time to generate and parse.

                                                                                                                          Fortunately you can detect nearly all these by running the feed through a validator. Do this any time you edit your generator code/template.

                                                                                                                          For anyone wanting to write a feed reader: you’ll definitely want something like libTidy, which can take “tag soup” and turn it into squeaky clean markup. Obviously important for the XML, but also for article HTML if you plan on embedding it inside a web page — otherwise errors like missing close tags can destroy the formatting of the enclosing page. LibTidy also improves security by stripping potentially dangerous stuff like scripts.

                                                                                                                          The one thing in this article I disagree with is the suggestion to use CSS to style article content. It’s bad aesthetically because your articles will often be shown next to articles from other feeds, and if every article has its own fonts and colors it looks like a mess. Also, I think most readers will just strip all CSS (we did) because there are terrible namespace problems when mixing unrelated style sheets on the same page.

                                                                                                                          PS: For anyone doing research on historical tech flame wars, out-of-control bikeshedding, and worst-case scenarios of open data format design — the “feed wars” of the early/mid Oughts are something to look at. Someone (Mark Pilgrim?) once identified no less than eleven different incompatible versions of RSS, some of which didn’t even have their own version numbers because D*ve W*ner used to like to make changes to the RSS 2.0 “spec” (and I use that term loosely) without bumping the version.

                                                                                                                          1. 5

                                                                                                                            Not using entry UUIDs and then changing the article URLs. Caused lots of complaints like “the reader marked all the articles unread again!”

                                                                                                                            I have unsubscribed from certain blogs because of this. It’s no fun when they keep “posting” the last 10 articles all the time…

                                                                                                                            1. 1

                                                                                                                              It drives me mad when I occasionally update my feeds and suddenly have tens, or hundreds (!) of “new” articles.

                                                                                                                              Doesn’t happen often enough that I’d want to delete the feed, but still very annoying.

                                                                                                                            2. 3

                                                                                                                              Someone (Mark Pilgrim?) once identified no less than eleven different incompatible versions of RSS,

                                                                                                                              I suspect this is because of intense commitment to the robustness principle (Postel’s Law). Tim Bray rebutted Dave Winer and Aaron Swartz’s frankly goofy devotion to this idea. I think it’s better to follow Bray’s advice.

                                                                                                                              1. 6

                                                                                                                                Actually it was Pilgrim and Aaron Schwartz he was rebutting in that blog post, not Winer.

                                                                                                                                And the 11-different-versions madness had nothing to do with liberal parsers, but with custody battles, shoehorning very different formats under the same name (RDF vs non-RDF), Winer’s allergy to writing a clear detailed spec or at least versioning his changes to it, and various other people’s ego trips.

                                                                                                                                In my experience, writing a liberal parser was a necessity because large and important feed publishers were among those serving broken feeds, and when your client breaks on a feed, users blame you, said users including your employer’s marketing department. Web browsers have always been pretty liberal for this reason.

                                                                                                                                1. 1

                                                                                                                                  Actually it was Pilgrim and Aaron Schwartz he was rebutting in that blog post, not Winer.

                                                                                                                                  Oh, right. Typed the wrong name there. Not gonna go back and edit it, though.

                                                                                                                              2. 2

                                                                                                                                There’s one good alternative to using UUIDs: tag URIs. They have one benefit over UUIDs: they’re human readable.

                                                                                                                                I remember the feed wars! Winer’s petulance caused so much damage. I haven’t used anything but Atom since then for anything I publish, and I advise people to give the various flavours of RSS a wide berth.

                                                                                                                              1. 4

                                                                                                                                “ As a user, you can force allow zooming”

                                                                                                                                Isn’t this problem solved, then?

                                                                                                                                1. 21

                                                                                                                                  No. Just because there’s an option to enable it, that doesn’t mean disabling it should be encouraged. Not everyone knows about the option, for one thing.

                                                                                                                                  1. 10

                                                                                                                                    You’ve identified a web browser UI design problem, which can be solved by the probably-less-than-double-digits number of teams developing popular web browsers, rather than by asking tens of millions of web content creators to change their behavior.

                                                                                                                                    1. 5

                                                                                                                                      Perhaps browser makers can treat it like a potentially undesirable thing. Similar to “(site) wants to know your location. Allow/Block” or “(site) tried to open a pop up. [Open it]”

                                                                                                                                      So: “(site) is trying to disable zooming. [Agree to Disable] [Never agree]” or similar.

                                                                                                                                    2. 8

                                                                                                                                      I think the better question is why can you disable this in the first place. It shouldn’t be possible to disable accessibility features, as website authors have time and time again proven to make the wrong decisions when given such capabilities.

                                                                                                                                      1. 3

                                                                                                                                        I mean, what’s an accessibility feature? Everything, roughly, is an accessibility feature for someone. CSS lets you set a font for your document. People with dyslexia may prefer to use a system font that is set as Dyslexie. Should it not be ok to provide a stylesheet that will override system preferences (unless the proper settings are chosen on the client)?

                                                                                                                                        1. 3

                                                                                                                                          Slippery slope fallacies aren’t really productive. There’s a pretty clear definition of the usual accessibility features, such as being able to zoom in or meta data to aid screen readers. Developers should only be able to aid such features, not outright disable them.

                                                                                                                                          1. 6

                                                                                                                                            I think this is a misunderstanding of what “accessibility” means. It’s not about making things usable for a specific set of abilities and disabilities. It’s about making things usable for ALL users. Color, font, size, audio or visual modality, language, whatever. It’s all accessibility.

                                                                                                                                          2. 1

                                                                                                                                            https://xkcd.com/1172/

                                                                                                                                            (That said, I don’t understand why browsers let sites disable zoom at all.)

                                                                                                                                        2. 6

                                                                                                                                          Hi. Partially blind user here - I, for one, can’t figure out how to do this in Safari on IOS.

                                                                                                                                          1. 3

                                                                                                                                            “Based on some quick tests by me and friendly people on Twitter, Safari seems to ignore maximum-scale=1 and user-scalable=no, which is great”

                                                                                                                                            I think what the author is asking for is already accomplished on Safari. If it isn’t, then the author has not made a clear ask to the millions of people they are speaking to.

                                                                                                                                            1. 4

                                                                                                                                              I am a web dev dilettante / newbie, so I will take your word for it. I just know that more and more web pages make browsing them with my crazy pants busted eyes are becoming nearly impossible to view on mobile, or wildly difficult enough so as to be equivalent to impossible in any case :)

                                                                                                                                              1. 4

                                                                                                                                                And that is a huge accessibility problem. This zoom setting is a huge accessibility problem.

                                                                                                                                                My point is that the solution to this accessibility problem (and almost all accessibility problems) is to make the browser ignore this setting, not to ask tens of millions of fallible humans to update literally trillions of web pages.

                                                                                                                                                1. 4

                                                                                                                                                  As another partially blind person, I fully agree with you. Expecting millions of developers and designers to be fully responsible for accessibility is just unrealistic; the platforms and development tools should be doing more to automatically take care of this. Maybe if the web wasn’t such a “wild west” environment where lots of developers roll their own implementations of things that should be standardized, then this wouldn’t be such a problem.

                                                                                                                                                  1. 2

                                                                                                                                                    Agreed. Front end development is only 50% coding. The rest is design, encompassing UX, encompassing human factors, encompassing accessibility. You can’t apply an “I’m just a programmer” or “works on my machine” mindset when your code is running on someone else’s computer.

                                                                                                                                                    1. 2

                                                                                                                                                      Developers and designers do have to be responsible for accessibility. I’m not suggesting that we aren’t.

                                                                                                                                                      But very often, the accessibility ask is either “Hey, Millions of people, don’t do this” or “Hey, three people, let me ignore it when millions of people do this”. And you’re much better off lobbying the three people that control the web browsers to either always, or via setting, ignore the problem.

                                                                                                                                          1. 2

                                                                                                                                            It’s not the use of sed, it’s the use of -i. Oh man, be so careful if you use that option.

                                                                                                                                            1. 1

                                                                                                                                              Using find . -exec sed is dangerous in a git repo

                                                                                                                                              Yes, agreed. I started programming with Perl, and one pet peeve that has stuck with me is when people use the -i flag without specifying a backup for potential recovery. It’s a terrible practice.

                                                                                                                                            1. 1

                                                                                                                                              What is the point of that paper exactly?

                                                                                                                                              1. 4

                                                                                                                                                To point out that existing protocols for IDEs (or whatever) to talk to language services are insufficient and to propose one way to address it: by reconfiguring the IDE automatically to account for the different protocols that are required to talk to the services for the language.

                                                                                                                                                1. 3

                                                                                                                                                  I think the abstract provides a clear summary.

                                                                                                                                                1. 3

                                                                                                                                                  Does the corresponding libstdc++ release support std::format? That’s the only modern C++ feature that I’ve missed on platforms where GCC is the system compiler.

                                                                                                                                                  1. 2

                                                                                                                                                    No.

                                                                                                                                                  1. 20

                                                                                                                                                    Warning: this is not supposed to be taken very seriously. It’s not a joke, but I won’t bet 2 cents that I’m right about any of it.

                                                                                                                                                    Pretty much all widely used languages today have a thing. Having a thing is not, by far, the only determinant factor in whether a language succeeds, and you can even question whether wide adoption is such a good measure of success. But the fact is, pretty much all languages we know and use professionally have a thing, or indeed, multiple things:

                                                                                                                                                    • Python has simplicity, and later, Django, and later even, data science
                                                                                                                                                    • Ruby has Rails and developer happiness (whatever that means)
                                                                                                                                                    • Go had simplicity (same name, but a different thing than Python’s) and concurrency (and Google, but I don’t think that it counts as a thing)
                                                                                                                                                    • PHP had web, and, arguably, Apache and cheap hosts
                                                                                                                                                    • JavaScript has the browser
                                                                                                                                                    • Typescript has the browser, but with types
                                                                                                                                                    • Java had the JVM (write once, run everywhere), and then enterprise
                                                                                                                                                    • C# had Java, but Microsoft, and then Java, but better
                                                                                                                                                    • Rust has memory safety even in the presence of threads

                                                                                                                                                    Even older languages like SQL, Fortran, Cobol, they all had a thing. I can’t see what Hare’s thing might be. And to be fair, it’s not a problem exclusively with, or specially represented by, Hare. 9/10 times, when there’s a post anywhere about a new language, it has no thing. None. It’s not even that is not actually particularly well suited for it’s thing, it can’t even articulate what it’s thing is.

                                                                                                                                                    “Well, Hare’s thing is system’s programming” that’s like saying that McDonald’s thing is hamburgers. A thing is more than a niche. It’s … well, it’s a thing.

                                                                                                                                                    It might well be the case that you can only see a thing in retrospect (I feel like that might be the case with Python, for instance), but still, feels like it’s missing, and not not only here.

                                                                                                                                                    1. 3

                                                                                                                                                      It might well be the case that you can only see a thing in retrospect

                                                                                                                                                      Considering how many false starts Java had, there was an obvious and error-ridden search process to locate the thing—first delivering portability, mainly for the benefit of Sun installations nobody actually had, then delivering web applets, which ran intolerably poorly on the machines people needed them to run on, and then as a mobile device framework that was, again, a very poor match for the limited hardware of the era, before finding a niche in enterprise web platforms. Ironically, I think Sun did an excellent job of identifying platforms in need of a thing, seemingly without realizing that their thing was a piss-poor contender for being the thing in that niche. If it weren’t for Sun relentlessly searching for something for Java to do, I don’t think it would have gotten anywhere simply on its merits.

                                                                                                                                                      feels like it’s missing

                                                                                                                                                      I agree, but I also think it’s a day old, and Ruby was around for years before Rails. Although I would say that Ruby’s creator did so out of a desire for certain affordances that were kind of unavailable from other systems of the time—a Smalltalk placed solidly in the Perl-Unix universe rather than isolated in a Smalltalk image. What we seem to have here is a very small itch (Zig with a simpler compiler?) being scratched very intensely.

                                                                                                                                                      1. 2

                                                                                                                                                        Ruby and Python were in the back of my mind the whole time I was writing the thing about things (hehe), and you have a point about Java, that thing flailed around A LOT before settling down. Very small itch is a good summary.

                                                                                                                                                        Time will tell, but I ain’t betting on it.

                                                                                                                                                        1. 1

                                                                                                                                                          I’m with you. But we’ll see, I guess.

                                                                                                                                                      2. 3

                                                                                                                                                        Pretty much all widely used languages today have a thing. […] Even older languages like SQL, Fortran, Cobol, they all had a thing

                                                                                                                                                        An obvious language you do not mention is C. What’s C’s thing in that framework? And why couldn’t Hare’s thing be “C, but better”, like C# is to Java? (Or arguably C++ is to C, or Zig is to C)

                                                                                                                                                        1. 12

                                                                                                                                                          C’s thing was Unix.

                                                                                                                                                          1. 4

                                                                                                                                                            Incorrect…C’s thing was being a portable less terrible macroassembler-ish tool.

                                                                                                                                                          2. 3

                                                                                                                                                            Well, I did say a thing is not the only determinant for widespread adoption. I don’t think C had a thing when it became widely used. Maybe portability? It was the wild wild west days, though.

                                                                                                                                                            Hare could very well eat C’s lunch and became big. But being possible is far away from being likely.

                                                                                                                                                            1. 2

                                                                                                                                                              C’s thing is that it’s a human-friendly assembly.

                                                                                                                                                              strcpy is rep stosb, va_list is a stack parser, etc.

                                                                                                                                                              1. 5

                                                                                                                                                                But it’s not. At least not once you turn on optimizations. This is a belief people have that makes C seem friendlier and lower level, but there have been any number of articles posted here about the complex transformations between C and assembly.

                                                                                                                                                                (Heck, even assembly isn’t really describing what the CPU actually does, not when there’s pipelining and multiprocessing going on.)

                                                                                                                                                                1. 2

                                                                                                                                                                  But it is. Sure, you can tell the compiler to optimize, in which case all bets are obviously off, but it doesn’t negate the fact that C is the only mainstream high-level language that gets you as close to the machine language as it gets.

                                                                                                                                                                  That’s not a belief, it’s a fact.

                                                                                                                                                                  1. 4

                                                                                                                                                                    you can tell the compiler to optimize, in which case all bets are obviously off

                                                                                                                                                                    …and since all deployed code is optimized, I’m not sure what your point is.

                                                                                                                                                                    Any modern C compiler is basically humoring you, taking your code as a rough guideline of what to do, but reordering and inlining and unrolling and constant-folding, etc.

                                                                                                                                                                    And then the CPU chip gets involved, and even the machine instructions aren’t the truth of what’s really going on in the hardware. Especially in x86, where the instruction set is just an interpreted language that gets heavily transformed into micro-ops you never see.

                                                                                                                                                                    If you really want to feel like your C code tells the machine exactly what to do, consider getting one of those cute retro boards based on a Z-80 or 8086 and run some 1980s C compiler on it.

                                                                                                                                                                    1. -1

                                                                                                                                                                      No need to lecture and patronize if you don’t get the point.

                                                                                                                                                                      C was built around machine code, with literally every language construct derived from a subset of the latter and nothing else. It still remains true to that spirit. If you see a piece of C code, you can still make a reasonable guess to what it roughly translates to. Even if it’s unrolled, inlined or even trimmed. In comparison with other languages, where “a += b” or “x = y” may translate into the pages of binary.

                                                                                                                                                                      Do you understand the point?

                                                                                                                                                                      1. 2

                                                                                                                                                                        C Is Not a Low-level Language

                                                                                                                                                                        The post you’re replying to isn’t patronizing you, it’s telling the truth.

                                                                                                                                                                        1. 2

                                                                                                                                                                          You are missing the point just the same.

                                                                                                                                                                          It’s not that C generates an exact assembly you’d expect, it’s that there’s a cap on what it can generate from a given piece of code you are currently looking at. “x = y” is a memcpy at worst and a dereferencing a pointer does more or less just that. Not the case with C++, leave alone Go, D, etc.

                                                                                                                                                                          1. 1

                                                                                                                                                                            I suggest reading an intro to compilers class textbook. Compilers do basic optimizations like liveliness analysis, dead store eliminations etc. Just because you write down “x = y” doesn’t mean the compiler will respect it and keep the load/store in your binary.

                                                                                                                                                                            1. -1

                                                                                                                                                                              I suggest trying to make a rudimentary effort to understand what others are saying before dispensing advice that implies they are dolts.

                                                                                                                                                                        2. 2

                                                                                                                                                                          If you see a piece of C code, you can still make a reasonable guess to what it roughly translates to.

                                                                                                                                                                          As someone who works on a C compiler for their day job and deals with customer support around this sort of thing, I can assure you this is not true.

                                                                                                                                                                          1. 2

                                                                                                                                                                            See my reply to epilys.

                                                                                                                                                                            Can you share an example of resulting code not being even roughly what one was expecting?

                                                                                                                                                                            1. 4

                                                                                                                                                                              Some general observations. I don’t have specific examples handy and I’m not going to spend the time to conjure them up for what is already a thread that is too deep.

                                                                                                                                                                              • At -O0 there are many loads and stores generated that are not expected. This is because the compiler is playing it safe and accessing everything from the stack. Customers generally don’t expect that and some complain that the code is “stupid”.
                                                                                                                                                                              • At -O1 and above, lots of code gets moved around, especially when inlining and hoisting code out of loops. Non-obvious loop invariants and loops that have on effect on memory (because the user forgot a volatile) regularly result in bug reports saying the compiler is broken. In nearly every case, the user expects all the code they wrote to be there in the order they wrote it, with all the function calls in the same order. This is rarely the case.
                                                                                                                                                                              • Interrupt code will be removed sometimes because it is not called anywhere. The user often forgets to tag a function as an interrupt and just assumes everything they write will be in the binary.
                                                                                                                                                                              • Our customers program microcontrollers. They sometimes need timing requirements on functions, but make the assumption that the compiler will generate the code they expect to get the exact timing requirements they need. This is a bad assumption. They may think that a series of reads and writes from memory will result in a nearly 1-1 correspondence of load/stores, but the compiler may realize that because things are aligned properly, it can be done in a single load-multiple/store-multiple instruction pair.
                                                                                                                                                                              • People often expect one statement to map to a contiguous region of instructions. When optimizaton is turned on, that’s not true in many cases. The start and end of something as “simple” as x = y can be very far apart.

                                                                                                                                                                              This is just from recent memory. There is really no end it. I won’t get into the “this instruction sequence takes too many cycles” reports as those don’t seem to match your desired criteria.

                                                                                                                                                                              1. 1

                                                                                                                                                                                Thanks. These are still more or less in the ballpark of what’s expected with optimizations on.

                                                                                                                                                                                I’ve run into at least a couple of these, but I can remember only one case when it was critical and required switching optimizations off to get what we needed from the compiler (had to with handling very small packets in the nic driver). Did kill a day on that though.