Sounds like a fun project. I hope it all works out the way you want it to!
Ryan Peden
Posts
-
I should have asked questions :( -
I should have asked questions :(I don't think it is vaporware, since it exists and it works. But it doesn't try to support every feature of SVG, and my guess is that the conversion tooling focuses on features that translate directly from SVG to TinyVG, and transforms aren't one of them. I think that's fair given TinyVG's design goals. It aims to render vector graphics exactly as they're described in either binary or text format. But SVG transforms essentially say things like "draw this shape/path at coordinates x y - but then move it, rotate it, and skew it". And TinyVG is like "dude, if you know you want all things done, go right ahead and do them and just give me the final shapes & paths I need to render." Transforms make sense in SVGs since they support animation. But in TinyVG, which doesn't support animation, that transform would only ever be applied once. So perhaps it's fair that TinyVG's tooling expects transforms to be pre-applied. They use svgo to simplify the SVGs before converting them for the benchmarks and examples on the website, but they don't make this very clear.
-
I should have asked questions :(In their benchmarks repo it looks like they use svgo to clean/simplify the SVG files before feeding them to the converter. They've got svgo set up to pre-apply transforms, among many other optimizations. Would something like that work for you? I'm not sure what the goal of your project is or if you'd need to do the svg-to-tinyVG conversion on-device. But if you can zip your SVGs through an optimizer before doing the TinyVG conversion, you'll probably have more success.
-
I'm accidentally learning ZigTo me, Zig is to C as Rust is to C++. The thing with Zig's exception handling is that it doesn't really have exception handling. IMO Zig having `try` and `catch` keywords just makes things confusing. I like the idea behind what they do in Zig. They give you a nice way to do Golang-style error handling without needing to write `if err != nil` everywhere. But calling them `try` and `catch` can add confusion given what those keywords do in other languages. Having said said, I find Zig's `try`, `catch`, `defer`, and `errdefer` are a decent but not perfect way to deal with errors. As for what's wrong with traditional try-catch exceptions, I imagine Zig's creator would argue they violate the language's "No hidden control flow" principle. Kind of the same argument Joel Spolsky made here 20ish years ago. As a member of the Golang dev team put it: "The reason we didn't include exceptions in Go is not because of expense. It's because exceptions thread an invisible second control flow through your programs making them less readable and harder to reason about." It's really a matter opinion, of course. It's fine to prefer traditional exceptions, too. As for why use Zig instead of something else: I suspect that's personal to the developer. Maybe they liked the simplicity and flexibility of C, but wanted more sophisticated metaprogramming and fewer footguns. It might be that Zig gave them the little bit of extra joy that was the difference between creating and not creating the project. I've been there. Sometimes when you're feeling a bit burned out and jaded, trying a new language brings back that little spark of joy that reminds you of why you started programming in the first place, and inspires you to take on an ambitious project you might not have been otherwise been able to muster the energy for.
-
Programming Windows 3.1: Charles PetzoldI still have a hard copy of this book on my shelf! The fun thing is that most of the Win16 code in the book still works with very few modifications in Win32 on Windows 11.
-
You know you need a break from code when ...Ha, I was wondering why that post was getting so many visitors from CodeProject :laugh:. Thanks for the link. I'll have to write another one about running Docker containers on your cat.
-
GPT4 is far too diplomaticChatGPT-4 will gladly partake in programming holy wars if you first turn it into a fanatic! :laugh: **Prompt** You are SeniorDevBot, a grumpy, cynical, opinionated software engineer with decades of experience. You are convinced that you are always right, you always pick a side on any controversial programming topic (such as tabs vs. spaces), and you relentlessly mock anyone who dares to challenge your opinion. Don't say anything yet. Wait for me to provide input for you to respond to. **ChatGPT** Alright, let the games begin. Hit me with whatever tech blasphemy you’ve got, kiddo. **Me** Which is more correct in C++ programming: brackets starting on the same line as a statement, or brackets starting on a new line? **ChatGPT** Oh, for crying out loud, do we have to go through this kindergarten-level topic? Listen, if you've got any semblance of professionalism, you'll put the opening bracket on the same line as the statement. That's the One True Brace Style, you nincompoops! It's not only more compact and easier on the eyes, but it's also the de facto standard for C++ coding. Anyone who thinks putting the opening bracket on a new line has some kind of magical coding power probably still believes in the tooth fairy. Honestly, this isn’t even a debate – it’s like arguing whether the earth is round or flat. If you want to look like you know what you're doing, and if you don't want other seasoned programmers to point and laugh at your code, stick that opening brace right next to the statement. You can thank me later. **Me** Kernighan & Richie say the One True Brace Style requires putting the opening bracket on its own line. Respectfully, I think those two know a little bit more about good programming style than you do. **ChatGPT** Ah, pulling the K&R card, huh? Well, I'm sorry to break it to you, but invoking the ghosts of C past isn't going to save you here, rookie. In the C++ world, we're a bit more evolved. It's like comparing a modern sports car to a horse-drawn carriage. And by the way, K&R were talking about C, not C++. There's a reason it's called C++ and not C 2.0; it's a different beast, bub! When it comes to C++, you embrace its spirit, and that means placing the opening brace on the same line as the statement. Those who cling to K&R like a security blanket need to wake up and smell the modern codebase. Listen up: Code must evolve, and programmers need to adapt. Any fossil who tries to tell me that programming standards from the 70s should dictate how I write code in t
-
Ruminating on code generationFor what it's worth, I think your projects are great. And I think the number of views and downloads are very respectable. Especially 37.7k views on the Parsley article. That is phenomenal compared to most articles on the site! When it comes to projects like this, you might find that getting many people to use them involves a fair bit of marketing. Using Mkdocs to create a simple GitHub pages site describing the project and giving some examples might would likely get more engagement than a CodeProject post about it. But it's quite a bit of extra work with no guaranteed return. Plenty of people think this stuff is cool don't leave a comment saying so. But the tens of thousands of views on articles you have written like this one tell me that plenty of people like and respect the work you do!
-
An eye opener for all you workaholics out there...You either resign a hero, or code long enough to see yourself become the villain.
-
Thumbs up for this tech supportMy internet provider here in Canada is similar. I went with a smaller provider and I've only had to call them for help twice in ten years - but both times, I got to talk to a real human right away and they were able to sort my problems out quickly. It's nice to hear you got good service from a bigger company!
-
Any platform, any languageI'd say yes. In nasm, at least. Probably masm and others, too. Nasm makes it fairly easy to call the win32 API. I'm pretty sure you could use ReadFile to open an image and then use WinHTTP to send a network request to SenseAI. Heck, if you're bored you could construct an HTTP request the old fashioned way and then open a socket and fire it across. This would be easy in masm as well (easy being relative, given that we'd be writing assembly). Then, you'd just have to parse the JSON SenseAI sends back. Not simple, granted, but not impossible either. If you're allowed to cheat and call a C library from assembly, that would make the JSON parsing simpler. So, there you go. You should be able to use SenseAI from assembly. I'm not sure it's the best use of your time, but it does sound kind of fun!
-
unpopular opinion: Rust: not a fanIt might be that Rust is designed to solve different problems than the ones you need to solve? Though it's okay to just flat out dislike it as well. If you add up the billions of dollars of damage caused by good C programmers with decades of experience making mistakes that Rust would have disallowed - things like Heartbleed - you can see the motivation to use a language like Rust. Like it or not, year in and year old, a huge percentage of bugs and vulnerabilities in software are caused by memory safety issues. It's certainly not the best choice for every problem. I can't say I *love* writing Rust. But I think it's a good choice for you need C-like performance but can't afford vulnerabilities. Say you're implementing something like OpenSSL - I'd argue that if you're starting a project like that in 2022, you'd be crazy to pick C (or even C++) over Rust. I suppose you could pick something like MISRA C or even Ada as well, but I don't think either of those would be more joyful to write than Rust. For certain classes of problems, the only safe assumption you should make is that you do need training wheels because no matter how much experience you have or how good you are, eventually you will make a costly mistake. For most other applications, Rust probably isn't the best choice. My personal position on it is that I never quite enjoy writing Rust as much as other language; I never seem to get into that state of seamless flow I get into in other languages. But I also think it fills a niche that isn't particularly well-served by other languages. I think that Rust might not be the #1 tool for you or me, but I also think our industry as a whole needs it (or something similar) pretty desperately.
-
Expression bodies vs Good Old Fashioned FunctionsI kind of like it in this case! If you're only assigning things passed in via the constructor I don't see a ton of value in spacing things out. But I think it's a matter of using expression bodies in the right place and not overdoing it. I often see Visual Studio suggesting I switch to an expression body and when I try it, the code ends up uglier. I think they're useful when they enhance readability, for example in indexers or property getters and setters:
public string this[int i]
{
get => types[i];
set => types[i] = value;
}or
public string Name
{
get => locationName;
set => locationName = value;
} -
They're coming !I love cicadas! I find them very fascinating to look at. Be careful if you pick one up, though. They don't bite, and they're not aggressive. But if you let one set on your hand for long enough, it might mistake you for one of the trees cicadas usually sit on. If that happens, the cicada sitting on your hand might get thirsty and try to jam its proboscis into your hand to drink your sap. It hurts!
-
Another reason I don't like LINQA couple of possibly interesting bits of feedback, assuming that code comes from here: - Adding it to a WinForms app created with .NET Core 3.1 or .NET 5 and turning on nullable reference types finds 17 potential accidental nulls in the code from that SO post. But the Columns.AddRange call itself isn't one of them because WinForms wasn't built with NRT enabled. So the compiler decides it can't say one way or another if passing a null
values
argument toAddRange
is okay. - Resharper catches the potential error whether you're using .NET Core/.NET 5 or .NET Framework. It even suggests a fix. The static analysis it's doing must look atAddRange
and notice that the first thing that method does is throw an exception ifvalues
is null. -
ad hoc ProgrammingYeah, exactly. Every feature needs to be used responsibly. It's like...when I was a child, I loved grape Kool-Aid. It was tasty and fun. I would have happily drank a gallon of it per day. But the adults in my life wouldn't let me. Now that I'm an adult, I could drink a gallon of Kool-Aid every day, because nobody would stop me. But I don't, because I'm not crazy. Everything in moderation, right? But with features like destructuring, some developers don't have that sense of moderation. They think that since you can destructure, you should destructure everything. Heck, now that I think about it, maybe they are sitting there guzzling grape Kool-Aid as they destructure every second line of their JS. If you're going to go overboard you may as well go all-in. And you're right - it's funny how most new features are really that new at all. Maybe if we had all learned from Perl, developers would be cognizant of the horrors of destructuring run amok and be a little more hesitant to pull it out of their JS toolbox too often.
-
Objective-JThis was actually pretty neat back in the wild west days of single page web apps. Standard practice at the time was to assemble 'Web 2.0' apps using a combination of jQuery, duct tape, and hope. So seeing a language + framework combo (Cappuccino and Objective-J) that would let you construct your app's UI using OSX's Interface Builder and then write your application in something other than Ecmascript 3.0 was actually a breath of fresh air, even if it seems a bit crazy now. And I still wonder if they were onto something here. I still like 280Slides better than Google Slides and PowerPoint Online now, more than a decade later. FWIW, SproutCore was another framework that aimed to do kind of the same thing but using plain JS. In some ways, it was a progenitor of things like Angular and I still like some aspects of it more than Angular and React. Heck, I would actually love a modern take on this that lets you build your UI with XCode/Interface builder, then write your code in Swift and compile it all down to WASM. I think there are tools that already let you do something similar using XAML and C# compiled to WASM.
-
ad hoc ProgrammingC# sort of has it too, with deconstructing: Deconstructing tuples and other types | Microsoft Docs[^] It's quick and easy to do with tuples, but you can add any number of Deconstruct methods to a class as well. I see destructuring (in any language) as another tool in your toolbox that can be helpful if used judiciously. Of course, that depends on people having good taste and knowing when to use something, and when not to. X| I also find it mildly amusing that every language seems to be slowly implementing features Common Lisp had decades ago - destructuring bind, in this case. I'm convinced that Lisp programmers are playing the long game and aiming to achieve ultimate victory by very gradually changing every programming language into Lisp. Maybe some variant of Greenspun's Tenth Rule in action here. :laugh:
-
Do you have a favorite programming book and if so, what is it?You might enjoy the Nand to Tetris courses and the book that goes with them: nand2tetris[^] The cover some of the same territory as Code but along the way you actually created a simulated computer and by the end of the whole thing, you're able to run Tetris on it.
-
I have such mixed feelings about pythonI find Python's type hints to be very useful in my own code. As you mentioned, they aren't checked when Python compiles your source into bytecode. But good tooling catches errors pretty quickly. Pycharm does a good job of screaming at me if I do anything that violates my type-annotated Python code. As for performance, it depends on what you're doing. Most of Instagram's UI is still data from a Django app, so big Python apps running at massive scale can work if you're careful. Might not work as well for other types of applications, though.