Announcement

Collapse
No announcement yet.

Qt Getting In On Generative AI, Starts By Adding GitHub Copilot To Qt Creator

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    Originally posted by ddriver View Post
    Consider tho, them 6-7 "different" projects do not necessarily give you better substance than the ONE project, important enough to merit such scrutiny. Doing one critical project right can teach you and reward you way more than a bunch of trivial and non-challenging ones. Yet again, that "quantity over quality" notion. You are kinda like saying "I don't need to fix that heart disease, that's too expensive and requires discipline to form new healthier habits, I'll just fix myself better by getting hair transplants, new dental veneers, color contact lenses and a set of new clothes and shoes. Now that's a way to get tangible results and FAST
    Fair point. However:
    1. I'm hardly a novice at this, even if I've been allowing my public projects to languish.
    2. I do rewrite stuff, but I prefer it to be because of my own innate sense of perfectionism, not because of the code equivalent of the dumb justification I was once given for Sphinx being such a terrible API documentation tool, that "You're supposed to be spending 30% of your time on documentation anyway".
    Heck, part of the reason I like Rust so much is how that "fearless refactoring" slogan is no empty boast.​

    Originally posted by ddriver View Post
    It was " industry standard" according to the senior devs, pretty much how it was probably industry practice to have 20 people barely managing to hold together something that, if designed properly, could easily be handled by a couple of devs
    Sounds like "Enterprise OOP". Funny enough, picking up Rust was pretty easy for me because I'd already shunned that and organically evolved a data-oriented, loosely-coupled style to make my code more pleasant to maintain and easier to write automated tests for.

    Originally posted by ddriver View Post
    Oh, also, you are not supposed to "keep reinventing and re-implementing" on a per project basis, you do initially, but down the line you realize "oh, I can actually have my own framework I can reuse across". I mean, if you don't write reusable code, you should probably quit.
    Yeah, but that argument can take you all the way to "It's wasteful to do anything short of writing your own reusable macro assembler routines". I don't want to be yet another case of "Ugh. Chromium took years to support the X11 SELECTION properly, this Electron app doesn't switch tabs in response to the scroll wheel, and the custom context menu lacks the simultaneous support for Windows-style 'click to open, click to select' and Mac-style 'press to open, drag, release to select' that's characteristic of native Linux apps."

    Originally posted by ddriver View Post
    Always have YOUR clearly defined API, always use your API, never use anything 3rd party directly in your code.
    I do. It's called "Write as much as possible in Rust libraries that I can reuse in as many different languages and projects as possible, then import it from Python and use PyQt to write a frontend for it.

    Originally posted by ddriver View Post
    And finally, keeping dependencies down to a minimum is always a good idea. Writing rust apps which use qt through qml through python and a bunch of other tools to glue legacy stuff together.... what now? Yeah, sounds like a real elegant solution.
    QML and Python in the same project? Now that IS a mess... though, if The Qt Company ever gets it into their head to offer memory-safe Rust bindings for the QWidget APIs, I'll gladly write my frontends in Rust too.

    I consider QWidget and memory-safe APIs non-negoriable, which means either PyQt/PySide or QtJambi... and I do NOT like Java.

    Besides, they're not Rust apps that use Qt and QML through Python. They're Python apps where the backend happens to be a library written in Rust. Standard maxim of combining Python with other languages: Extend, Don't Embed.

    Rust's got the most idiot-proof dependency handling (when you consider the big picture, including Cargo, the ecosystem's attitude toward API stability, and the default static linkage), so do as much as possible in Rust, then use maturin to bundle it all into a single statically-linked Python dependency. Ideally, make that backend and PyQt or PySide the only dependencies the Python frontend has.

    Originally posted by ddriver View Post
    And no, you can't "glue together qml functionality" out of qwidgets - a module that doesn't even have a notion of most of the functionality QML provides, you can hack together a rudimentary legacy GUI kit - something that's rather dwindling in popularity and at this point - wildly redundant.
    I don't remember saying I was glueing together QML functionality. I said I was using Python in the same "glue together C++/Rust components" role that QML serves.

    ...and I think it's quite rich to say "rudimentary" when I see pro-QML arguments as comparable to pro-Wayland arguments... Wake me when they stop crowing over working HDR (which I don't use) and start implementing DE-agnostic APIs to let users consent to have the active window title monitored by task-tracking applications (which I consider non-negotiable).

    On several occasions, I've been interested in writing or rewriting applications that don't need to feel KDE-native (eg. fullscreen apps with a more Kodi/EmulationStation-esque UI, TTS+IR Remote interfaces where the GUI is just a convenient way to receive the input events and display diagnosable state, etc.) and, every time, I've found that Qt Quick would, at best, double the time it'd take me because I'd need to either rewrite components or override undesirable elements of existing ones, or the features I needed were added in a version of Qt newer than the earliest distro release I wanted to support.
    Last edited by ssokolow; 08 June 2023, 04:36 AM.

    Comment


    • #32
      Originally posted by ssokolow View Post

      Rust's got the most idiot-proof...
      And that appeals to you for some reason Funny thing that people's rather adopt a whole new language to solve a basic problem, rather than solve it themselves.

      I ultimately went on to write a basic memory manager, which I now use for just about everything. It can create objects with dynamic layouts, so you can create data types which do not exist during compilation. It is as fast as raw memory access but without the management hassle, and it supports a custom notification mechanism which can trivially be mapped to any concrete object model. So whatever representation happens to acquire a specific data range, it automatically notifies any user referencing the data range. Then I have a unified C++ and QML APIs to work with that binary data.

      That was one of my main gripes with QML - it didn't frigging have the data types and objects are binarily useless, I'd rather have my explicit 8 16 32 and 64 bit primitives and consistent layout structs. So implementing a low overhead, high performance self-managing and notifying dynamic layout thread safe persistent state data engine was the straightforward solution. Not adopting more idiot proof tooling, but going for something straightforward and obvious, or doing the non-idiot thing I suppose.

      See, if you hurry and adopt a crutch for every inconvenience, pretty soon your workspace will be full of crutches that get in the way and trip you over. And then you believe your tooling to be subpar, when it is your workflow that brings out the worst of your tooling. Sadly, yours is the "industry" approach - always throwing more code, memory and cpu cycles at the problems, whose source is precisely having too much code, memory and clock cycles. Not a great plan!

      Comment


      • #33
        Originally posted by ddriver View Post
        And that appeals to you for some reason Funny thing that people's rather adopt a whole new language to solve a basic problem, rather than solve it themselves.
        I use Rust for the same reason macro assemblers died out as the primary target for application development.

        Higher-level, more abstract languages with stronger type systems enable you to teach the compiler to enforce more invariants, and make depending on other people's code more viable.

        I don't have infinite hours in the day, and I'm not some magical superhuman who never has tired days or distracted moments.

        I can program in C, and I do for retro-hobby use... but I much prefer languages where I can focus more on results and less on making up for limitations in the compiler or ecosystem. (That's why, when I'm doing DPMI stuff instead of real-mode DOS programming, I'd choose Free Pascal for writing DPMI applications for DOS. It benchmarks comparably to Java or C#, has a stronger type system than C, and has a "batteries included" standard library with things like Free Vision (a Turbo Vision port), a .zip implementation, and various other things.)​​

        Well... unless it's DPMI stuff in the same codebase as real-mode DOS stuff. Then I stick to Open Watcom C/C++ for both to keep the toolchain setup simple.

        Originally posted by ddriver View Post
        I ultimately went on to write a basic memory manager, which I now use for just about everything. It can create objects with dynamic layouts, so you can create data types which do not exist during compilation. It is as fast as raw memory access but without the management hassle, and it supports a custom notification mechanism which can trivially be mapped to any concrete object model. So whatever representation happens to acquire a specific data range, it automatically notifies any user referencing the data range. Then I have a unified C++ and QML APIs to work with that binary data.
        ...and that's great when that's what you need, but one of the things younger me had to un-learn was perfectionism to the point of hyper-optimizing some tiny component like a URL normalizer and then burning out. I choose my mix of technologies based on the project in question. I just find QWidget via PyQt the best fit most of the time.

        Originally posted by ddriver View Post
        That was one of my main gripes with QML - it didn't frigging have the data types and objects are binarily useless, I'd rather have my explicit 8 16 32 and 64 bit primitives and consistent layout structs. So implementing a low overhead, high performance self-managing and notifying dynamic layout thread safe persistent state data engine was the straightforward solution. Not adopting more idiot proof tooling, but going for something straightforward and obvious, or doing the non-idiot thing I suppose.
        Which is one reason I prefer "Write the backend as a library in Rust, expose it as an importable module using PyO3, and then write the frontend using PyQt to glue that library to PyQt". I've got C++-like control on the backend without spending all that time to track down an edge-case segfault because I underestimated how tired I was on that one day a month ago, and for the stuff where QML would be used as I/O-bound glue, there are MyPy type definitions for it, unlike QML which, as far as I know, can't be TypeScript'd.

        Originally posted by ddriver View Post
        See, if you hurry and adopt a crutch for every inconvenience, pretty soon your workspace will be full of crutches that get in the way and trip you over. And then you believe your tooling to be subpar, when it is your workflow that brings out the worst of your tooling. Sadly, yours is the "industry" approach - always throwing more code, memory and cpu cycles at the problems, whose source is precisely having too much code, memory and clock cycles. Not a great plan!
        I think I'm going to end our conversation here. It sounds like you're persisting in arguing against your preconceptions of my position, rather than my actual position.

        (eg. One of the reasons I use Rust and QWidget together with PyQt existing only for the I/O-bound stuff is that I detest bloated programs... something which also led me to discover that, embarrassingly for GQView/Geeqie and GTK+, a first-draft re-creation of the Collection view using PyQt's QImage bindings loads cached thumbnails twice as fast as whatever Geeqie's doing in C with GdkPixBufLoader, even before I turned off "clamp QThreadPool concurrency to 1 in case the backing store is a rotating drive" and got linear scaling up to the number of CPU cores this machine has. Why do I resent Firefox on my system? Because web browsers are the only thing where there's no "a whole order of magnitude faster" competitor I can switch to or write.)

        For example, one project I'm doing in QWidget widgets is a frontend for human-assisted OCRing of manga to feed into Google Translate. Actually handling off to the Tesseract OCR backend is the only part that doesn't complete instantaneously in my PyQt+PyOpenCV+Tesseract codebase. (And let me tell you, there's annoyingly little documentation on how to hand decoded image data back and forth between PyQt/PySide and PyOpenCV with minimal copying.) My next goal? Learn all the tricks for making Tesseract OCR faster.

        (That particular project doesn't really have much of a "backend", so I've held off on making Rust an additional dependency. It's 99% glue like turning a click on a QGraphicsView into a PyOpenCV flood-fill in the selection mask (magic wand select) and discard of interior contours in the fill (selecting the text too when clicking on the speech balloon's background).)

        So far, the part that's taken the most time/attention was probably debugging support for accepting images via drag-and-drop or copy-paste, since there are so many varied and subtle non-compliances with the relevant specs... but at least I now have a test corpus for it. (Did you know that Chrome/Chromium will sometimes randomly forget to offer raw image data as a requestable data type when using drag-and-drop instead of copy-paste?)

        QMimeData is analogous to a JSON/TOML/YAML decoder. It'll handle getting the drop/paste metaformat/protocol decoded, but it does nothing to help with the higher-level protocol for encoding lists of files inside hunks of text. "This application uses file:// URLS while that one uses strings with weird escaping/quoting when dropping files. That application uses file://localhost/ for some reason, which confuses some things unless you check for and null out the hostname first. The spec rules on whether URL lists should use \n or \r\n for delimiters, but some applications don't comply. etc. etc. etc."

        I'd rather not also intentionally embrace playing that sort of whac-a-mole with the ability of the widgets to match platform conventions.
        Last edited by ssokolow; 08 June 2023, 01:09 PM.

        Comment


        • #34
          Originally posted by ssokolow View Post

          I can program in C, and I do for retro-hobby use... but I much prefer languages where I can focus more on results and less on making up for limitations in the compiler or ecosystem. (That's why, when I'm doing DPMI stuff instead of real-mode DOS programming, I'd choose Free Pascal for writing DPMI applications for DOS. It benchmarks comparably to Java or C#, has a stronger type system than C, and has a "batteries included" standard library with things like Free Vision (a Turbo Vision port), a .zip implementation, and various other things.)​​
          You are not making up for limitations, you are implementing your own framework rather than directly using 3rd party stuff or keeping it to primitive constructs, therefore actually heping you understand better the low level requirements and produce more elegant solutions rather than relying on language magic . Bohoo, C doesn't have automatic memory management, and manual is so hard, therefore lets not use C.

          I mean it is not like we can write an unmanaged memory manager ONCE, using unmanaged memory only once, in a single, safe, controlled and limited scope. Nah, doing manual memory managed right once - that's too much to expect out of a cutting edge rust developer. Nah, C is clearly garbage, therefore lets be rust hipsters, cuz we like it easy and to feel proud about it, Rust - the latest in the line of magic solutions, the cure-all that fixes everything makes it OK to be lousy and yet will still somehow save us from ourselves.

          Not being spoon fed a ready to use out of the box solution for anything and everything - that is not a limitation, that's actually opportunity to learn how to do things right. If you rely on training wheels, you will get used to them, require them at all time, and the result of your work will suffer for it.​

          A few years back, some people had the "brilliant" idea of "everything wasm" slow and inefficient runtime universal across computing and even implement the os kernel in wasm. This time we are gonna do it all in rust, lets port the same old stiff designs to a new language because it is not about it being a mess, but about what language it is written in. Saying the same thing in a different language can make the wrong into right.
          Last edited by ddriver; 09 June 2023, 05:52 AM.

          Comment


          • #35
            Originally posted by ddriver View Post

            You are not making up for limitations, you are implementing your own framework rather than directly using 3rd party stuff or keeping it to primitive constructs, therefore actually heping you understand better the low level requirements and produce more elegant solutions rather than relying on language magic . Bohoo, C doesn't have automatic memory management, and manual is so hard, therefore lets not use C.
            It's not "hard", it's "tedious". I can do it... but I can also do calculations with pen an paper instead of using a pocket calculator or Python's REPL. I have enough self-esteem to not need to engage in masochistic demonstrations of prowess.

            Originally posted by ddriver View Post
            I mean it is not like we can write an unmanaged memory manager ONCE, using unmanaged memory only once, in a single, safe, controlled and limited scope. Nah, doing manual memory managed right once - that's too much to expect out of a cutting edge rust developer. Nah, C is clearly garbage, therefore lets be rust hipsters, cuz we like it easy and to feel proud about it, Rust - the latest in the line of magic solutions, the cure-all that fixes everything makes it OK to be lousy and yet will still somehow save us from ourselves.
            No, Rust is a language that prioritizes keeping the need to reason about program behaviour local. That's why the unsafe keyword is a core part of the language. You write efficient memory-unsafe stuff, then you wrap it up in an API that the language can enforce correct usage of so that, no matter how tired or distracted you are; No matter what idiot newbie they bring onto the team, it won't result in you getting called into the office on the weekend or at 3AM to fix an intranet application that's costing them tens of thousands of dollars for every minute it's down.

            Originally posted by ddriver View Post
            Not being spoon fed a ready to use out of the box solution for anything and everything - that is not a limitation, that's actually opportunity to learn how to do things right. If you rely on training wheels, you will get used to them, require them at all time, and the result of your work will suffer for it.​
            Again, feel free to engage in your masochistic reinvention of wheels if that's what you need to feel good about yourself. I'll be acting like an actual professional and recognizing that other people are capable of writing code that matches or exceeds what I can write.

            Originally posted by ddriver View Post
            A few years back, some people had the "brilliant" idea of "everything wasm" slow and inefficient runtime universal across computing and even implement the os kernel in wasm. This time we are gonna do it all in rust, lets port the same old stiff designs to a new language because it is not about it being a mess, but about what language it is written in. Saying the same thing in a different language can make the wrong into right.
            1. Sane programmers don't "rewrite everything in Rust just because". We do targeted rewrites of things that actually have maintenance or security issues. Google's WUFFS is also a good choice for parsers. In fact, if the added maintainability complexity of adding a new compile-to-C language to your codebase doesn't tip the balance, it's a better choice than Rust for parsers.
              (eg. librsvg was incrementally rewritten in Rust partly because its old CSS parser was unmaintained and presenting recurring security issues while Rust has the one from Servo that Firefox now relies on as part of Quantum CSS.)
            2. Remember what you said about rewrites being a good thing if they fix bad design? I'm taking the opportunity to rewrite my old projects in Rust where maintainability is a problem, because it gives me a chance to jettison the more "Enterprise OOP"-y designs I was doing in the early 2010s and before, as well as to leverage Rust's first-class support for sum types in modelling data and data flows more naturally.

            Comment

            Working...
            X