[HN Gopher] Pretty.c
___________________________________________________________________
Pretty.c
Author : synergy20
Score : 322 points
Date : 2024-10-24 03:01 UTC (19 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| mydriasis wrote:
| Wow, neat! The wildest part to me is
|
| > And it's backwards-compatible with C and all of its libraries!
|
| I can't wait to give it a shot! This looks like a riot.
| geon wrote:
| Have you heard of Zig?
| oguz-ismail wrote:
| It requires a different compiler. This is just a collection
| of C preprocessor macros
| ptspts wrote:
| The Zig toolchain can compile both Zig and C.
| klardotsh wrote:
| Yes, but the Zig toolchain is not
| $YOUR_EXISTING_C_COMPILER_YOU_ALREADY_KNOW_AND_USE
| textread wrote:
| Is it possible to tangle the Readme into pretty.h? In other
| words, are the codeblocks in the orgfile exhaustive.
|
| I love the literate way you have explained your thought process
| in the readme.
| aartaka wrote:
| Yes, code blocks in Org are executable, but I was aiming for
| simple embedding and zero build-time, thus conservative choice
| of separating README and the actual header.
| OsrsNeedsf2P wrote:
| This is terrifying
| aartaka wrote:
| Thanks!
| yjftsjthsd-h wrote:
| I have not decided how I feel in general, but:
|
| > Everyone defines these, so why not provide them?
|
| Honestly, that's fair.
| dymk wrote:
| > turn any codebase into a beginner friendly one
|
| Okay then.
|
| I was hoping to see a "this is just for fun" disclaimer but
| didn't see one. Please never actually use this in a project that
| other people will have to read or contribute to.
| ipsum2 wrote:
| > Provide so much syntactic sugar as to cause any C developer a
| diabetes-induced heart attack.
|
| seems like its obvious to me that its a joke
| rebolek wrote:
| It's a joke that I would happily use.
| AnthonBerg wrote:
| C is funny, in many ways.
| aartaka wrote:
| You're welcome!
| thiht wrote:
| Not everything needs to be stated explicitly, where's the fun
| in that?
| TheRealPomax wrote:
| No promises, people who want to have fun are going to have fun
| despite requests not to have fun.
| ipsum2 wrote:
| `equal(0.3, 0.2 + 0.1); // true`
|
| how is this wizardry possible?
| defrost wrote:
| Is _What Every Computer Scientist Should Know About Floating-
| Point Arithmetic_ wrong ??!!
|
| addendum: _why are obviously rhetorical questions are taken so
| literally here?_
| leansensei wrote:
| Because text doesn't convey sarcastic voice tonality, so the
| intent is far from obvious.
| defrost wrote:
| Sarcastic? Okay, if you say so.
|
| Picking out an obvious define function that compares a
| float with a float sum of that nature should indicate an
| good understanding of _why_ that might be called wizardry
| and deserving of a second look.
|
| Hats off to the peer comment that suggested scaling against
| epsilon rather than simpliy regurging the substitution "as
| was" from the header.
|
| The scaling is better in general, optional in some specific
| contexts.
| ipsum2 wrote:
| It's meant as both humorous and a nerd snipe :)
| slimsag wrote:
| it uses absolute difference epsilon equality ('close enough to
| be considered equal'): static int
| pretty_float_equal (float a, float b) { return fabsf(a - b) <
| FLT_EPSILON; } static int pretty_double_equal (double
| a, double b) { return fabs(a - b) < DBL_EPSILON; }
| static int pretty_long_double_equal (long double a, long double
| b) { return fabsl(a - b) < LDBL_EPSILON; }
| vbezhenar wrote:
| This is wrong code. It only works somewhat correctly when a
| and b around 1.
| stabbles wrote:
| Yeah, should be scaled like |x - y| <= e * max(|x|, |y|)
| aartaka wrote:
| Will do.
| jffhn wrote:
| If both terms are infinites and of same sign, subtraction
| will give NaN and it will fail.
| listeria wrote:
| How is that a problem? infinities shouldn't be considered
| equal
| jffhn wrote:
| For IEEE 754, and in Java for example, they are. Only NaN
| is not equal to itself (and different from itself).
| wjbr wrote:
| static int pretty_float_equal (float a, float b) { return
| fabsf(a - b) < FLT_EPSILON; }
| masklinn wrote:
| It uses type dispatch to perform an epsilon comparison:
| static int pretty_float_equal (float a, float b) { return
| fabsf(a - b) < FLT_EPSILON; }
|
| So it's https://docs.python.org/library/math.html#math.isclose
| hmry wrote:
| This code is incorrect, but I don't blame them. :) Probably
| one of the most common float-related mistakes, even among
| people who "know how floats work".
|
| FLT_EPSILON is the difference between 1.0 and the next larger
| float. It's impossible for numbers less than -2.0 or greater
| than 2.0 to have a difference of FLT_EPSILON, they're spaced
| too far apart.
|
| You really want the acceptable error margin to be relative to
| the size of the two numbers you're comparing.
|
| Also, everyone should read the paper "What, if anything, is
| epsilon?" by Tom7
| im3w1l wrote:
| I would go even further and say that any equality
| comparison of float numbers has to be a one-off special
| case. You need to know how much error can arise in your
| calculations, and you need to know how far apart
| legitimately different numbers will for your particular
| data. And of course the former has to be smaller than the
| latter.
| aartaka wrote:
| Indeed, FLT_EPSILON is not a one-size-fits-all solution,
| but it's good enough for frequent case of comparing big
| enough numbers, which is not covered by regular ==. So it's
| a convenience/correctness trade-off I'm ready to make.
| hmry wrote:
| If the numbers you are comparing are greater than 2,
| abs(a - b) < FLT_EPSILON is equivalent to a == b. Because
| it's not possible for two large numbers to not be equal,
| but also closer together than FLT_EPSILON.
| jdthedisciple wrote:
| what // FLT_EPSILON == 0.01
| equal(4.999, 5); // true 4.999 == 5; //
| false
|
| am i missing?
| hmry wrote:
| FLT_EPSILON is not 0.01, it's 0.00000011920929.
|
| But it's impossible to have a number that's
| 0.00000011920929 less than 5.0, or 0.00000011920929 more
| than 5.0, because the floats with enough magnitude to
| represent 5 are spaced further apart than that. Only
| numbers with magnitude < 2 are spaced close enough
| together.
|
| In other words, the only 32-bit float that's within
| +-0.00000011920929 of 5.0 is 5.0 itself.
| jdthedisciple wrote:
| Oh you're right, thanks for the explanation!
|
| Gotta research now where the 0.00000011920929 number
| comes from...
| masklinn wrote:
| It's the distance between 1.0 and the next representable
| float.
| jdthedisciple wrote:
| I got that but I am curious how to derive that number.
|
| Is it representable as a non-trivial ratio of integers?
| hmry wrote:
| Good question! It's 1/(2**23), because 32 bit floats have
| 23 bits after the decimal point
| looopTools wrote:
| I cannot wait to show this to a colleague of mine. He will kill
| me XD
| aartaka wrote:
| Can't wait to learn of how it went!
| bitwize wrote:
| I'm reminded of the guy who did #define BEGIN {
| #define END }
|
| and a whole bunch of other macro-larkey just to make C look more
| like Pascal. Only then would he deign to code in it.
| epcoa wrote:
| https://en.wikipedia.org/wiki/Stephen_R._Bourne
|
| https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh
| sph wrote:
| Now that's just silly. And I see the backwards keyword
| terminators (LOOP/POOL).
|
| I have wondered why we have case/esac, if/fi but while/done.
| I imagine the author himself figured that while/elihw would
| just be entirely ridiculous.
| pavlov wrote:
| Just call it wyl/lyw. Pronunciation maintained, problem
| solved.
| giucal wrote:
| > I have wondered why we have case/esac, if/fi but
| while/done.
|
| With the reverse-keyword convention we'd get "od", not
| "elihw", though. while ... for ...
| do do ... ... od
| od
|
| The 'od' utility already existed, apparently, so Bourne
| opted for "done".
|
| [edit: typos]
| azinman2 wrote:
| > Deprecate Lua, Python, JavaScript, Ruby and a dozen other
| languages, because Pretty C is the ultimate scripting language,
| but lightning-fast and strongly typed!
|
| Umm... that's quite the goal.
|
| I'll stick with deprecated Python.
| fancyfredbot wrote:
| Deprecate Python?! You'll have to deprecate me first! ;-)
| psychoslave wrote:
| We will all reach this status at some point, though the silly
| code we produced might stick a bit longer in some legacy
| codebase. :D
| Uptrenda wrote:
| Type names are nice; Perfect choice for the in-built func macros
| (like min); Len -- love it. Named boolean operators -- might be a
| bit much but go for it; Ternaries are illegible so you can only
| improve them; Not completely sold on all your loop definitions
| but some make sense to me; Resource tracking is impressive; The
| for... look a bit ugly -- could probably call it something else.
|
| All in all: quite a solid attempt. I'll give you 8/10 for the
| design of this. The way you sketched this out in C using macros
| is really elegant. This actually looks like good code. Would I
| use it? It's a new language and I like C already. It could help
| people learn C and think about language design. Since the way
| you've done this is very clear.
| aartaka wrote:
| Well, you don't have to use it all. My projects mostly use
| booleans, len(), max/min, and some operator aliases, because
| there wasn't much need for other tasty stuff yet. So give it a
| shot, even if for a couple of operator macros!
| Uptrenda wrote:
| You know I expected your macro file to be unreadable moon
| math. But it actually doesn't look bad.
| Validark wrote:
| Evil, yet beautiful. Hats off to you.
| aartaka wrote:
| Thanks!
| lpapez wrote:
| All that is missing is a garbage collector. Should be possible to
| implement one by overriding malloc & friends?
| vidarh wrote:
| You can use the Boehm-Demers-Weiser GC with C. It's
| conservative, because it has to be with C, so it may/will miss
| things (it will treat integers etc. as potential pointers, and
| so avoid freeing anything "pointed to" by them), and so it
| works best as an extra layer of protection/leak detector, but
| it can be used as a replacement for freeing memory too.
| gpuhacker wrote:
| Reminds me of a C++ codebase I once had to inspect that was
| entirely written as if it were written in Java. With camelcase
| naming for everything, getters and setters for every class
| variable, interfaces everywhere.
| bpye wrote:
| Good job they weren't using MSVC I guess...
|
| https://learn.microsoft.com/en-us/cpp/cpp/property-cpp?view=...
| jart wrote:
| You ain't seen nothin. Check out the bourne shell source code
| from unix seventh edition. https://minnie.tuhs.org/cgi-
| bin/utree.pl?file=V7/usr/src/cmd... I can't believe it's not
| ALGOL.
| teruakohatu wrote:
| Wow, I was not expecting that! Was this style of C common
| back then?
|
| Before he wrote the Bourne shell the author wrote an ALGOL
| compiler, and ALGOL inspired Bourne syntax:
|
| https://en.wikipedia.org/wiki/ALGOL_68C
| pasc1878 wrote:
| There were article suggesting #define BEGIN { and #define
| end }; to make C look more like Pascal.
|
| I think in Europe C was not as common as other languages at
| the time so the terseness looked odd.
| pavlov wrote:
| Also because the special characters were (and are)
| difficult to type on European keyboards.
|
| Characters like []{}\|~ are behind multi-finger access
| and often not printed at all on the physical keys (at
| least in the past). You can see how this adds a hurdle to
| writing C...
|
| Pascal was designed by a European, so he preferred
| keywords which could be typed on every international
| keyboard. C basically just used every symbol from 7-bit
| ASCII that happened to be on the keyboards in Bell Labs.
| smatija wrote:
| Just as example, on my slovenian QWERTZ layout: [ -
| altgr+f, ] - altgr+g, { - altgr+b, } - altgr+n, \ -
| altgr+q, | - altgr+w, ~ - altgr+1.
|
| You get used to them, though you start feeling like a
| pianist after a short coding session. The one most
| annoying for me are the fancy javascript/typescript
| quotes, which I have to use all too often: ` - altgr+7.
| ulbu wrote:
| Today I learned that there exist people who use non-US
| layouts when coding. That's spectacular!
| pavlov wrote:
| How did you think people outside the US learn
| programming?
| anthk wrote:
| setxkbmap us -option ctrl:swapcaps -option compose:rwin
|
| Problem solved. US layout, and with the right Window keys
| you can compose European characters.
| pavlov wrote:
| There's so many assumptions here about a person who's
| starting to learn programming.
|
| For starters, that they're on Linux, they feel
| comfortable running complex CLI commands, they can
| memorize the U.S. layout just like that, and that they
| can type without looking at the physical keys (because
| changing the virtual mapping means keys produce something
| else than what the label says).
|
| In reality, the learner's first exposure to C family
| languages is more likely to be a website where you can
| run some JavaScript in a text box. And the first hurdle
| is to figure out how to even type {}. American developers
| just completely forget about that.
| anthk wrote:
| On the long term, using the native keyboard hinders
| yourself a lot. I tried to do so with the Spanish (es)
| layout, it's pretty much unergonomical.
|
| It's looks like being deliberately designed for
| press/office usage and not for proper programming.
| SSLy wrote:
| or maybe popular proglangs were designed for writing on
| USAn press/office keyboards - remember that UNIX came to
| be as a typesetting appliance -- disregarding anyone
| else.
| pavlov wrote:
| I've been writing C and its progeny (C++, JavaScript,
| Rust etc.) since 1990 on a Finnish keyboard.
|
| The AltGr brackets are fine. The truly annoying character
| to type is the backtick (which is a quite new addition to
| the pantheon of special characters, C doesn't use it).
|
| My personal opinion is that Niklaus Wirth had the better
| overall ideas about clarity and inclusiveness in
| programming language design, but that battle is long
| lost. (What you consider the character set needed for
| "proper programming" is really a relatively new
| development, mid-1990s and later.)
| schoen wrote:
| Backticks were fairly important for shell scripting in
| the past, but have officially been replaced with $(),
| which can be nested.
|
| My intuition is that Perl would be the most challenging
| on a keyboard where it's harder to type unusual
| punctuation, since it feels like a very punctuation-heavy
| language, but I don't know whether it actually uses more
| than C (I think the backtick has a shell-style meaning in
| Perl too).
| psychoslave wrote:
| >it's pretty much unergonomical.
|
| Well unless opting for something like Dvorak, you are
| indeed doomed to something that was specificcaly designed
| to please typewriter mechanical constraints without much
| care for the resulting ergonomics.
|
| I use a Bepo layout personally, on a Typematrix 2030 most
| of the time, as French is my native language.
| smatija wrote:
| I tried switching to US a few times, but every time
| muscle memory made me give up soonish - especially since
| there are big benefits to using same keyboard layout as
| other people in your office are using.
|
| Also practically everytime I need to write a comment,
| commit message or email I need my c, s and z. It's kinda
| nice to have them only a single keypress away.
| oezi wrote:
| My hack: use caps key to switch to local keyboard layout
| while holding it.
| dagw wrote:
| Love it! I use ctrl+space to switch, but your idea sounds
| even better
| cryptonector wrote:
| Spectacular?? Terrifying. If I need to type non-ASCII
| Latin characters I'll just use compose sequences. The
| thought of a non-U.S. keyboard layout with modifiers
| required to type []{}<> and so on is terrifying.
| fuzztester wrote:
| IIRC, Pascal had/has (* and *) as an alternative to { and
| } , from the start, or from early on - as syntax for
| start comment and end comment.
| froh wrote:
| https://minnie.tuhs.org/cgi-
| bin/utree.pl?file=V7/usr/src/cmd...
|
| wow.
|
| thanks for this gem.
| worstspotgain wrote:
| > camelcase naming for everything, getters and setters for
| every class variable, interfaces everywhere
|
| This is not far off from the guidelines in many cases, e.g.
| Windows code (well, not _every_ variable of course.) A lot of
| Java design was copied from C++.
| pasc1878 wrote:
| I had that as well but also Java passes strings in as f(String
| *) so the C++ code was f(new String("Hello")
| rauli_ wrote:
| I've seen similar codebases as well written by people who have
| spent way too much time with Java. One even had it's own String
| class which was just a wrapper for std::string with Java-like
| methods.
| shortrounddev2 wrote:
| I think that's just OOP
| aartaka wrote:
| You might like https://aartaka.me/oop-c
| leetsbehonest wrote:
| That is pretty cool
| unwind wrote:
| Meta: the naming is ... strange.
|
| The actual name of the repo is "pretty.c", but the name used for
| the language/dialect/result/horrorshow[*] is "Pretty C".
|
| The actual code file you include is called "pretty.h", which
| makes sense since it's a header, of course. Confusing!
|
| Edit: escapes.
|
| [*] Yes, I'm a C programmer, currently hunting for black-marked
| insulin to combat the rapid-onset diabetic attack from all that
| sugar. Sorta.
| nneonneo wrote:
| I mean, don't say the repo didn't warn you!
|
| > The goals for Pretty C are: Provide so much syntactic sugar
| as to cause any C developer a diabetes-induced heart attack.
| tromp wrote:
| > ifnt for if(!...).
|
| "unless" seems more readable than "ifnt".
| tux3 wrote:
| Another bikeshed is the infinite for(;;) loop being called
| "always"
|
| I've seen "loop" in other languages. But Qt calls it "forever",
| and that is indeed very pretty. Very Qt, even
| teruakohatu wrote:
| > I've seen "loop" in other languages. But Qt calls it
| "forever", and that is indeed very pretty. Very Qt, even
|
| You can break a "forever" loop so I think "loop" is a better
| name.
| wwalexander wrote:
| I don't know why "repeat" isn't very common in place of
| while/loop/etc; it works out nicely grammatically.
| repeat {} repeat while <condition> {}
| repeat {} while <condition> repeat <count> {}
| af78 wrote:
| One possible reason:
|
| > The word "REPEAT" should not be used in place of "SAY
| AGAIN", especially in the vicinity of naval or other
| firing ranges, as "REPEAT" is an artillery proword
| defined in ACP 125 U.S. Supp-2(A) with the wholly
| different meaning of "request for the same volume of fire
| to be fired again with or without corrections or changes"
| (e.g., at the same coordinates as the previous round).
|
| https://en.wikipedia.org/wiki/Procedure_word#Say_again
|
| More seriously, PASCAL has repeat-until loops, similar to
| do-while loops in C.
| aartaka wrote:
| Pretty C does aliases "repeat" for "do", so yeah, I've
| got you covered!
| krylon wrote:
| "indefinitely" might be a better name. (But I think loop is
| indeed a better name.)
| aartaka wrote:
| Added in commit ef510ca!
| layer8 wrote:
| I hope you also add a "definitely", for symmetry.
| aartaka wrote:
| "loop" added in commit 626408b, thank you!
| poincaredisk wrote:
| #define ever ;; for(ever) {}
| codetrotter wrote:
| #define never ;0; for(never) {}
| metalliqaz wrote:
| for(evernt) {}
| aartaka wrote:
| "forever" added in commit 67ff9ef, thank you!
| aartaka wrote:
| Indeed! But I've reserved "unless" for a ternary conditional,
| which is more useful anyway.
|
| Oh shit wait, you're John Tromp, BLC creator! I'm a fan!
| cdcarter wrote:
| On the other hand, ifnt is fun to say outloud.
| MrLeap wrote:
| love. It.
| aartaka wrote:
| Thanks!
| varjag wrote:
| This made me immediately think whether MIT Loop of Common Lisp
| was an inspiration here. Checked the user's profile and sure
| enough, a lisper!
| aartaka wrote:
| Yes, LOOP is a huge inspiration and my favorite programming
| language!
| DeathArrow wrote:
| This should have been invented 50 years ago!
| aartaka wrote:
| Yes, and it's a shame that underlying features were only
| shipped in C11 (generics) and C23 (auto type inference!)
| SuperHeavy256 wrote:
| So sweet :))
| aartaka wrote:
| Yeah, I love sugar ;)
| nneonneo wrote:
| It claims to be a scripting language but you still have to
| compile the programs. Boo! Add CINT
| (https://root.cern.ch/root/html534/guides/users-guide/CINT.ht...)
| and you can have instantaneous execution and even a REPL!
| shakna wrote:
| I'd prefer just using tcc [0]. Far lighter weight than that
| monster. And C, not C++.
|
| [0] https://bellard.org/tcc/tcc-doc.html
| maccard wrote:
| Given the idea behind this repo is to cause pain, why not add a
| shebang to your file [0] to make it executable.
|
| I saw a blog post a long time ago that went into the details of
| how ./foo worked, and how it executed an elf file. You could
| register `.c` programs in the same way to be compiled and run?
|
| [0]
| https://gist.github.com/jdarpinian/1952a58b823222627cc1a8b83...
| nneonneo wrote:
| Now I have a very evil idea: what about registering a binfmt
| handler for the header bytes "#include"? Sure, it doesn't
| handle _all_ C /C++ programs (notably any program that dares
| to start with a comment), but it would not require modifying
| any source code!
|
| (For even more insanity I guess you could also trigger on //
| and /*, although there's some risk of false positives then!)
| aartaka wrote:
| Well, who said that scripting language cannot be compiled? And
| yeah, Clang-REPL is another way to make it REPL-friendly.
| knome wrote:
| generally they aren't, as scripting usually implies an
| interpreter, though no one is stopping you from using a
| wrapping script that quietly compiles on first run and caches
| a bunch of executables somewhere. not much different than
| python producing bytecode files as it goes along.
| randomdata wrote:
| Script usually implies some kind of task that runs once and
| the exits. As opposed to a system that is expected to run
| indefinitely.
|
| There are good reasons for why scripts are often
| interpreted and why systems are often compiled, but that's
| not what defines them. There are definitely scripts that
| are compiled and systems that are interpreted out in the
| wild.
| knome wrote:
| 'scripting' is an ill-defined term with many
| interpretations, certainly.
| bityard wrote:
| Sure, there is no "rule" against it. But words/phrases have
| commonly-accepted meanings and willfully ignoring or
| appropriating those meanings implies either cultural
| ignorance or a concealed agenda.
|
| If you want to insist that scripting languages can be either
| compiled or interpreted, then its better to just drop it
| altogether and just say "language" because the "scripting"
| part has utterly lost its identity at that point.
| suzumer wrote:
| Cern uses cling now (https://github.com/root-project/cling)
| ngcc_hk wrote:
| Can we just pascal?
| aartaka wrote:
| I won't stop you, so be my guest.
| swiftcoder wrote:
| This is as horrific as it is wonderful.
| aartaka wrote:
| Thanks!
| nicman23 wrote:
| as someone that just started C, it looks pretty :)
| aartaka wrote:
| Thanks!
| codeflo wrote:
| Can someone clarify whether this is intended as a joke or whether
| the author is actually confused? I mean, nothing about this makes
| sense: it's not "scripting"; it claims to introduce "strong
| typing" while it does nothing about typing; it introduces all
| kinds of operator aliases "modeled after Lua and Lisp" that are
| present in neither of these languages. But it's not an obvious
| parody either, so I'm genuinely not sure.
| AnthonBerg wrote:
| I do not at all think the author is confused. Being confused is
| OK though.
| sandos wrote:
| I mean he has to be serious, right: "Deprecate Lua, Python,
| JavaScript, Ruby and a dozen other languages, because Pretty C
| is the ultimate scripting language, but lightning-fast and
| strongly typed!!"
| aartaka wrote:
| Author here. I don't see any problem with this
| byroot wrote:
| Well, as a starter C is rarely considered as "strongly
| typed". Statically typed yes, but strongly typed not so
| much.
| aartaka wrote:
| With C23 (nullptr, auto typing, typeof) and C11
| (generics) it got more guarantees and type-related
| primitives. You can still do void*, but you are strongly
| discouraged from it.
| byroot wrote:
| #include "pretty.h" void print_int(int
| value){ println(value); }
| int main (int argc, string argv[]) {
| long value = 23849234723748234;
| print_int(value); }
|
| How is this strongly typed? $ cc test.c
| -o test && ./test -1411401334
|
| And to be clear, weak vs strong isn't a boolean property
| but a spectrum, but would be hard to argue with a
| straight face than C is a strongly typed language.
| brabel wrote:
| C is likely the only example of a programming language
| that is clearly statically typed while at the same time
| being weakly typed. For a reason: as your example shows,
| it's a really bad idea (but understandable for a language
| from the 60's).
| layer8 wrote:
| C is from the 1970s.
|
| Java is weakly typed in its generics, despite being
| statically typed. I'm sure there are more examples.
| thiht wrote:
| That's pretty clearly said jokingly
| throwaway19972 wrote:
| Does "strong typing" now just mean "static typing"? Afaik both
| lua and python are already strongly typed. Javascript is not and
| I have no clue about ruby.
| lelanthran wrote:
| > Does "strong typing" now just mean "static typing"?
|
| The distinction strong and weak typing is irrelevant in
| practice.
|
| Weak (but present) static typing beats strong dynamic typing
| every single time, because what is valuable is _NOT_ _" Do I
| see a type mismatch error only when a user accesses it?"_, it's
| _" does this mismatch prevent a deployment?"_
|
| IOW, the only distinction in production is dynamic typing vs
| static typing, not strong typing vs weak typing.
| throwaway19972 wrote:
| > because what is valuable is NOT "Do I see a type mismatch
| error only when a user accesses it?", it's "does this
| mismatch prevent a deployment?"
|
| I argue that understanding the semantics clearly and
| unambiguously is the most relevant thing, and strong typing
| tends to do that better (imho--with my only other examples
| being javascript and the "stringly-typed" perl and some
| random irrelevant BASIC dialects).
|
| > Weak (but present) static typing beats strong dynamic
| typing every single time,
|
| Can you give me an example? I don't think I've ever heard of
| such a thing. The closest I can think to this is maybe,
| arguably, the use of `void*` pointers in C which is difficult
| to see as anything other than pragmatism rather than some
| deeply beneficial way to write code--even explicit casts
| produce much more readable code. Another argument I could see
| is for operator overloading, which (IMO) produces much less
| readable code, or the implicit conversions feature of Scala
| (which also, IMO, produces less readable code, but they've
| addressed a lot of the major problems with it).
| syrrim wrote:
| recommend setting up tests for your code s/t failures block
| deployment. can catch categories of bugs beyond typing errors
| w4rh4wk5 wrote:
| I've seen this implementation of defer a few times now. I really
| dislike calling this defer (like the keyword in Go) as the given
| code won't be executed on return.
| aartaka wrote:
| Scoping defer to a block is actually more useful and explicit
| than function-exclusive that Go does, so I consider that a
| feature.
| w4rh4wk5 wrote:
| No no, I think you misunderstood my critic. Defer working on
| block-scope is fine; however, if I exit the block through a
| return (or break), the deferred function is not called.
|
| To my knowledge, you need a compiler extension to implement
| this in C (or use a C++ destructor).
| shakna wrote:
| Well, there's a few things I should probably get around to adding
| to CNoEvil[0] and ogw[1]... There always seem to be more every
| few months when this project reappears.
|
| [0] https://git.sr.ht/~shakna/cnoevil3/
|
| [1] https://git.sr.ht/~shakna/ogw
| pineaux wrote:
| I feel compelled to try it out in a serious way and contribute to
| it. I have strong knowledge of python and am learning C. Are
| there good reasons -apart from attracting the ire of
| c-programmers- to not use it?
| aartaka wrote:
| Author here. I'll be glad to accept any contribution that makes
| C more readable, so PR away!
| nanis wrote:
| > if (argc above 1)
|
| I give up.
| aartaka wrote:
| You're welcome!
| fnord77 wrote:
| I feel like this would have been cool 25 years ago
| dfox wrote:
| The code asumes that C17 has C++-style auto (https://github.com/a
| artaka/pretty.c/blob/master/pretty.h#L11...), it does not (in C
| auto is storage specifier that is equivalent to no storage
| specifier).
| aartaka wrote:
| C17 doesn't have auto, but C23 does, and thus my
| `__STDC_VERSION__ > 201710L` (notice the greater than sign, it
| doesn't include C17 itself.)
| dfox wrote:
| Ha, apparently the N2310 working draft is not the last one :)
| Alifatisk wrote:
| If you find this interesting, you might like libcello.h aswell!
| https://www.libcello.org
| aartaka wrote:
| Yes, it's one of the inspirations!
| IgorPartola wrote:
| For what it's worth this makes the same mistake that Python 2
| did: string and bytes are not the same type and shouldn't be
| treated as such.
| umanwizard wrote:
| What is your definition of "string"?
|
| If it's "human-readable text", then fine, a string is not the
| same thing as an arbitrary byte array.
|
| But lots of languages don't enforce that definition.
| bobbylarrybobby wrote:
| Well that's the very thing: not enforcing that distinction is
| the very mistake in question.
| michaelsbradley wrote:
| Given the nature of it (pretty.c) and the stated intention of
| being "backwards-compatible with C and all of its libraries",
| what would make more sense than sticking with C's multibyte
| strings?
|
| https://en.cppreference.com/w/c/string/multibyte
| AlotOfReading wrote:
| What do you consider the type of shell text, i.e. what's in
| argv and what you get from subprocess output? It's not well-
| formed utf8 strings because any random garbage can be in there,
| yet tools like awk and grep are ubiquitous.
|
| I'd argue that strings and bytes are the same general type, but
| it's sometimes useful to give well-formed utf8 bytes a
| different type internally. Rust gets this mostly correct with
| OsString and String.
| ryandrake wrote:
| The way I understand it: Bytes are just bytes, until you
| provide an encoding. Then they can be can be converted to a
| string, if validly encoded. Taking an array of characters and
| just treating it or casting it as a string is usually a bad
| idea.
|
| The thing I think Rust maybe goofed, or at least made a
| little complicated, is their weird distinction between a
| String and a str (and a &str). As a newbie learning the
| language, I have no idea which one to use, and usually just
| pick one, try to compile, then if it fails, pick the other
| one. I'm sure there was a great reason to have two types for
| the same thing, that I will understand when I know the
| language better.
| steveklabnik wrote:
| I wrote a blog post that may help you!
| https://steveklabnik.com/writing/when-should-i-use-string-
| vs...
|
| If you want to understand more deeply, the Rust Programming
| Langauge, chapter 4, uses String and &String and &str to
| talk about ownership and borrowing. Here's a link to the
| start of that chapter: https://doc.rust-
| lang.org/stable/book/ch04-00-understanding-...
| ryandrake wrote:
| How timely and helpful, thanks!
|
| Your blog post is practical and clearly explains what to
| do, when, which is helpful. What's confusing is _why_
| Rust has the two types and why the language designers
| decided it was a good idea to have to convert back and
| forth between them depending on whether it was going in a
| struct or being passed as an argument. I suppose the
| "why" is probably better found in the Rust docs.
|
| As a long-time C++ user, it seems like std::string vs
| const char* all over again, and we somehow didn't find a
| better way.
| steveklabnik wrote:
| Yep, that's exactly it: I wanted to focus purely on what
| to do, rather than weigh it down with what's already in
| the Rust book.
|
| It's closer to std::string and std::string_view. But yes,
| in a language with value and reference semantics, when
| you also care about performance, you just can't do any
| better: you need both types. Or at least, if you want the
| additional correctness guarantees and safety provided by
| communicating ownership semantics in the type. C gets
| away with just char * but then you have to read the docs
| to figure out what you're allowed to do with it and what
| your responsibilities are.
| AlotOfReading wrote:
| In C++ terms, String is std::string, &str is
| std::string_view. They're different things, but they can
| appear similar.
| brabel wrote:
| A Rust `String` reference (i.e. &String) can always be
| passed where `&str` is expected because `String` has a
| `Deref<Target=str>` impl... in that sense they don't just
| appear similar, they are polymorphic.
| AlotOfReading wrote:
| There may not be a single encoding for every byte in a
| string. The encoding may not be knowable ahead of time. You
| might be trying to extract strings from a random blob of
| bytes with unknown origin. There's a thousand and one
| different variations.
|
| To give a real example, I once wrote some python scripts to
| parse serial messages coming off a bus. They'd read the
| messages, extract some values with regex, and move on.
|
| Unfortunately the bus had some electrical bugs and would
| intermittently flip random bits with no CRC to correct
| them. From my point of view, no big deal. If it's in
| something outside the fields I care about, I won't notice
| it. If it's flipped something I do care about we have a bad
| sample to drop or noise the signal processing will deal
| with. Either way, it's fine. Python on the other hand cared
| very much. I rewrote everything in C once I got
| sufficiently annoyed of dealing with it and more
| importantly explaining to others how they couldn't
| "simplify" things using the stdlib APIs.
| ptspts wrote:
| Python stdlib conveniently supports both byte strings and
| Unicode strings, even for regexps. Ther is no need to
| migrate to any other language.
| samatman wrote:
| I don't agree. This doctrine presumes all of the following:
| - String data will be properly encoded - There is one
| encoding of strings (UTF-8 usually) - Validation must
| occur when string data is created - Truncating a logical
| codepoint is never acceptable - You may not do string
| things to "invalid" bytes - Proper encoding is the
| beginning and the end of validation
|
| None of these things are consistently true. It's a useful
| practice to wrap validated byte sequences in a type which can
| only be created by validation, and once you're doing that,
| `Utf8String` and `EmailAddress` are basically the same thing,
| there's no reason to privilege the encoding in the type system.
| _benj wrote:
| > The goals for Pretty C are:
|
| > Provide so much syntactic sugar as to cause any C developer a
| diabetes-induced heart attack.
|
| :-D
| spacedcowboy wrote:
| As someone who just got diagnosed with type-1 diabetes (the
| auto-immune variety, not the "you eat too much sugar" variety),
| this was far more depressing than funny. I'm probably being
| overly-sensitive, but man my life has gone to shit in the last
| couple of years...
| jdthedisciple wrote:
| Sorry to hear.
|
| Honest advice: I have heard fasting + healthy diet can
| permanently fix diabetes (though I forgot which type)
|
| Maybe try it? Good luck in any case!
| pipeline_peak wrote:
| For each looks convoluted, you shouldn't have to list the type.
|
| It should be no harder than C#'s foreach(var i in list)
| aartaka wrote:
| Indeed, I might need to revisit foreach with type inference.
| Should be totally possible.
| sneed_chucker wrote:
| Creating DSLs within C has a long tradition.
|
| Stephen Bourne wanted to write his shell in ALGOL so badly that
| he relentlessly beat C with its own preprocessor until it began
| to resemble his preferred language.
|
| https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh...
| sheepscreek wrote:
| Here is an example of what we wrote using it:
|
| https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh...
| Keyframe wrote:
| This is not even half as bad as I expected it to be.
| mjan22640 wrote:
| Are variadic macros turning complete?
| ay wrote:
| Yes. https://github.com/rofl0r/chaos-pp
| jcmontx wrote:
| does this transpile to C or how does it actually work?
| jdthedisciple wrote:
| it's just aliases
|
| preprocessor is using those #defines to replace tokens in the
| code so it ends up as usual C
| taylorius wrote:
| Sorry for what is probably a stupid question. Does pretty.c act
| as a preprocessor or sorts, converting your pretty.c script into
| actual c, that is then compiled? Or is it a virtual machine that
| interprets your pretty.c script?
| aartaka wrote:
| It's a set of C Preprocessor macros, so you don't even need to
| somehow process the code--you just #include the header and hack
| away as if it was regular C!
| designed wrote:
| Preprocessor of sorts. From the readme:
|
| The goals for Pretty C are:
|
| - Provide so much syntactic sugar as to cause any C developer a
| diabetes-induced heart attack.
|
| - Deprecate Lua, Python, JavaScript, Ruby and a dozen other
| languages, because Pretty C is the ultimate scripting language,
| but lightning-fast and strongly typed!
|
| - Including only one header (yes, Pretty C is a header-only
| library #include-able from arbitrary C file!) to turn any
| codebase into a beginner friendly one.
| wffurr wrote:
| It's not a preprocessor or compiler. There's no binary. It's
| just a bunch of C code in a header: macros, functions, etc.
| that you can use to write different looking programs but that
| are still C.
| revskill wrote:
| Or just use Ruby.
| chris_wot wrote:
| I'm waiting for someone to write a lambda calculus based C++
| library that allows everything to be defined in terms of
| function. Peano axioms and all.
| jay-barronville wrote:
| This project looks really cool! Unfortunately, there's just way
| too much magic involved. In my humble opinion, C is simply not
| the language for this level of magic--extreme use of macros (and
| hidden behavior in general) is how you end up with hard-to-detect
| (and hard-to-debug) bugs and security vulnerabilities. As cool as
| this project looks, I'd never feel comfortable using it in
| anything serious. A+ for the effort though!
| kvirani wrote:
| > Provide so much syntactic sugar as to cause any C developer a
| diabetes-induced heart attack.
|
| Haha love this!
| stankot wrote:
| This reminded me of ArnoldC
|
| https://lhartikk.github.io/ArnoldC/
| shiomiru wrote:
| > max and min of two numbers.
|
| Influenced by windows.h I see :)
| cmcconomy wrote:
| someone's salty about tiobe!
| layer8 wrote:
| Given the title, shouldn't that be #include "pretty.c" instead of
| #include "pretty.h"?
___________________________________________________________________
(page generated 2024-10-24 23:01 UTC)