5 ms·
I find the section on "syntactic salt" interesting: > The opposite of syntactic sugar, a feature designed to make it harder to write bad code. Specifically, sy
by thrtythreeforty 4y ago
I find the section on "syntactic salt" interesting:
> The opposite of syntactic sugar, a feature designed to make it harder to write bad code. Specifically, syntactic salt is a hoop the programmer must jump through just to prove that he knows what’s going on, rather than to express a program action.
This is perhaps an uncharitable way to describe it, but the concept does ring a bell. Rust's unsafe {}, C++'s reinterpret_cast<>(), etc - all slightly verbose. More important than jumping through hoops, the verbosity helps when reading code to know that something out of the ordinary is going on.
- DonHopkins 4y agoAnd then there's Perl's "syntactic syrup of ipecac". https://en.wikipedia.org/wiki/Syrup_of_ipecac https://en.wikipedia.org/wiki/Syrup_of_ipecac
- zppln 4y ago> syntactic salt I feel like this describes Rust's lifetime annotations pretty well too.
- epage 4y agoNot just lifetimes but types used to do more complex lifetimes that are normalized by other languages like RefCell, Arc, etc.
- Karliss 4y agoI disagree about lifetime annotations being syntax salt. At least with my interpretation of what syntax salt. From syntax perspective lifetime annotations are almost as short as possible assuming you want to explicitly convey this information at all ('a is just two symbols and one of them is identifier). The alternative of not specifying it at all comes with major tradeoffs of either in memory safety (like in C) or runtime performance (like most programming languages with dynamic memory management). In theory there is third option of compiler fully deducing lifetimes, but that's far from trivial, has it's own costs and realistically even further narrow down what programs the compiler considers valid and increasing compilation time. There are strong similarities with typing strategies. Just because there are programming languages with dynamic typing doesn't mean that explicit static typing is salt. Dynamic typing has performance cost, and static inferred typing has worse self documentation properties and slightly bigger compilation time cost since you can't process each function independently. On the other hand reinterpret_cast<Foo*>(expr) doesn't provide to compiler any extra information that couldn't be conveyed with simpler less verbose syntax like R(Foo*)expr or (expr as Foo*). Same with unsafe{} blocks, compiler already know which operations are unsafe.
- nyanpasu64 4y agoWhat I can't stand about Rust is that the language developers think they know better than language users developing software. They stack on syntactic salt to make it more unpleasant to write the equivalent of correct C++ programs with aliased mutation or manual freeing, in situations where the idiomatic Rust ways are also unpleasant to write (Cell, RefCell, raw pointers), have runtime overhead (RefCell), are busywork to implement in working programs (restructuring your entire program around an ownership tree with only ephemeral stack-allocated cross-linking &mut, which is only sometimes possible without reducing performance or increasing memory use), or are easy, tempting, and undefined behavior in Rust but not C++ (casting *mut to &mut in an unsafe block in a safe function).
- athrowaway3z 4y ago"Man tries to hammer in screw. Angry at hammer manufactures for not being screwdriver manufactures" ---- I'll just edit this comment to clarify: Rust does a lot of thing really well. Non-RC manual memory management for a tree/graph structure is absolutely not it. As for the verbose 'unsafe' pointer/memory manipulations, i really don't see the issue. I've written my share and I think its fine to add a roadblock if you want to shoulder the ability to add segfaults and other issues into a codebase. Additionally, it usually helps that you decide to encapsulate it into the least number of unsafe functions, instead of 'doing it manually' all over a codebase.
- nyanpasu64 4y agoRust is intended to be a systems language capable of replacing C++ in its niche, and interfacing with existing C++ at a fairly coarse-grained level like Firefox's oxidation (though cxx is trying to enable rich interop passing richer types than C-ABI ones), so it's trying to be a better screwdriver more so than a hammer. So difficulty expressing C++ concepts is arguably a flaw, and difficulty implementing all software with the same CPU/memory overhead as C++ (which I'd argue is the case, though some would disagree) is definitely a flaw. It's like creating a new screwdriver bit or handle, trying to convert the world to it, then attracting a legion of followers arguing that manufacturing flat-head screwdrivers should expose you to legal liability for anyone who slips it out of the socket and injures themselves (ignoring that flat-head screws existed and will continue to exist).
- cxr 4y ago> More important [...] the verbosity helps when reading code to know that something out of the ordinary is going on This applies to JS as well with its strict equality check (triple equals). Bad practices within the NodeJS ecosystem, however, have led to circumstances where triple equals has been cargo culted as the "right" thing to do for any equality comparison. The consequences of this include code that is more verbose, is no more type safe (and often doesn't do the right thing for some inputs—whereas with double equals, in contrast, it would...), and that the appearance of triple equals is no longer a strong signal that there's something happening that's worth paying attention to.
- adamddev1 4y agoCan you give some examples of inputs where === doesn't do the right thing?
- cxr 4y agoSuppose you're working on a compiler. You want to add a feature flag or otherwise be able to produce a build that when run attaches rich diagnostics information to the emitted tokens to assist in debugging—let's say you're really interested in the source offset where a given token appeared, for example. Unless you've already really gone off the rails in other ways, then you can trivially do this just by making special mode compiler pass around String objects where your token processing routines expect a string—making sure you define a `position` property at the time of creation. This is possible because your input isn't overconstrained. It's an abstract data type. Using triple equals, on the other hand, will screw this up. Your inputs are now overconstrained—they must be string primitives. In other words, you've invented an unnecessary requirement <https://www.teamten.com/lawrence/programming/dont-invent-unnecessary-requirements.html https://www.teamten.com/lawrence/programming/dont-invent-unn...>.
- adamddev1 4y agoWow that's a well thought out and interesting example, thank you. I recently learned about `new String()` and wondered where people might use/get burned by that.
- deleted 4y ago[deleted]
- mvf4z7 4y agoThis reminds me of Reacts "dangerouslySetInnerHTML" prop. https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml https://reactjs.org/docs/dom-elements.html#dangerouslysetinn...
- tmtvl 4y agoI've heard it called "syntactic vinegar" instead. I wonder if there's a term for syntactic useless stuff, like commas in Clojure quasiquoted lists.
- lioeters 4y agoI propose "syntactic konnyaku". > Konnyaku is a rubbery, flavorless zero-calorie food made of yams that are high in fiber and added to various Japanese foods for its squishy texture.