15 votes

Fortnightly Programming Q&A Thread

General Programming Q&A thread! Ask any questions about programming, answer the questions of other users, or post suggestions for future threads.

Don't forget to format your code using the triple backticks or tildes:

Here is my schema:

```sql
CREATE TABLE article_to_warehouse (
  article_id   INTEGER
, warehouse_id INTEGER
)
;
```

How do I add a `UNIQUE` constraint?

27 comments

  1. [10]
    ssk
    Link
    Any Vim hacks or tricks for a beginner? Useful macros?

    Any Vim hacks or tricks for a beginner? Useful macros?

    2 votes
    1. [4]
      Jakobeha
      Link Parent
      If you haven't already, download neovim and set it up with a plugins. I recommend you use a NvChad or another prebuilt config, but if you want to learn, you could create your own (just plugin...

      If you haven't already, download neovim and set it up with a plugins.

      • I recommend you use a NvChad or another prebuilt config, but if you want to learn, you could create your own (just plugin manager + a few language servers and essential plugins). Even if you do create your own config, you could look at the NvChad source code for inspiration and good essential plugins, since it's very small.

      • I also recommend adding Copilot for neovim

      I don't have many tips for vim navigation/shortcuts, sorry. I think those are just muscle memory, eventually you get used to e to go to the end of a word, O to insert a line above the cursor, %s/search/replace/g to find and replace in a file, etc. Just use a Vim cheatsheet if you're not familiar with the key commands.

      3 votes
      1. [2]
        dave1234
        Link Parent
        Speaking of regex - does NeoVim support PCRE? Vim for Windows doesn't, and I feel like I'm constantly having to fight its built-in regex dialect.

        Speaking of regex - does NeoVim support PCRE? Vim for Windows doesn't, and I feel like I'm constantly having to fight its built-in regex dialect.

        1. Jakobeha
          Link Parent
          Not by default, but there's a plugin eregex. It hasn't been updated for a while but seems to still be alive / work. There's also vim-ripgrep, but it's under an alternate command and needs to be...

          Not by default, but there's a plugin eregex. It hasn't been updated for a while but seems to still be alive / work.

          There's also vim-ripgrep, but it's under an alternate command and needs to be hacked to support PCRE.

          1 vote
      2. actionscripted
        Link Parent
        Second this. If you’re a serious Vim user try NeoVim and dip a toe into Lua. Pre-builds like NvChad are an awesome way to see what’s possible but I would steer you to LazyVim and at minimum...

        Second this. If you’re a serious Vim user try NeoVim and dip a toe into Lua.

        Pre-builds like NvChad are an awesome way to see what’s possible but I would steer you to LazyVim and at minimum lazy.nvim. (NvChad seems to create their own versions of things and I think it can be better to have a more diverse ecosystem.)

        Once you get setup with lazy.nvim, LSPs, treesitter and the rest you’ll feel unstoppable.

        There’s a cool series that goes through all sorts of modern setup stuff at https://github.com/alpha2phi/modern-neovim

        Check out what Folke is doing. He’s like the Tim Pope of NeoVim: https://github.com/folke

    2. dave1234
      Link Parent
      I've started using :norm to apply a series of keystrokes to each line in a selection. For example, suppose you have a CSV file and wish to delete the first column. You could record a macro with q...

      I've started using :norm to apply a series of keystrokes to each line in a selection.

      For example, suppose you have a CSV file and wish to delete the first column. You could record a macro with q and then manually apply it to each line, but that's very slow.

      Instead: :norm ^dt,x (use normal mode, jump to start of line, delete everything to the first comma, then delete the comma).

      I'm sure it can do much more than just this.

      3 votes
    3. [3]
      yesnomaybe
      Link Parent
      The most useful 'trick' is learning to move around in the file efficiently and the more straightforward editor commands. A cheatsheet is a must; a physical copy may be better than having a spare...

      The most useful 'trick' is learning to move around in the file efficiently and the more straightforward editor commands. A cheatsheet is a must; a physical copy may be better than having a spare window available so you can refer to it constantly and it does need to be constantly. In the beginning, it will be quicker to press the right arrow a bunch than to look up and use the specific one or two keystrokes to move to the the next word, or what have you, but persevere and always try to do whatever you are doing with the least number of keystrokes. Initially, everything will take so much longer and you will keep losing your focus on whatever it is you are actually trying to achieve but, eventually, it will become ingrained and you will be so much faster (it's like going from a hunt and peck typist to a touch typist).

      There's some games that allow you to learn these keystrokes in a fun way - but you need to make sure you use vim frequently to maintain it, otherwise it'll all be forgotten a few days/weeks after you stop playing the game. e.g. https://vim-adventures.com/ and http://www.vimgenius.com/

      3 votes
      1. [2]
        ssk
        Link Parent
        This is exactly what I was looking for. Thank you so much!!

        This is exactly what I was looking for. Thank you so much!!

        1 vote
    4. archevel
      Link Parent
      I haven't used vim in quite a while, but I used to have a quite nice setup for doing development in golang with it. Have the dotfiles for it here if you're keen to see the setup. Haven't verified...

      I haven't used vim in quite a while, but I used to have a quite nice setup for doing development in golang with it. Have the dotfiles for it here if you're keen to see the setup. Haven't verified if it still works though (caveat emptor)!

      1 vote
  2. [6]
    JoshuaJ
    (edited )
    Link
    Hey Tiddlers, I would like some advice, I want to get better at designing programs. I’m writing python. I write pure functions without side effects. I model my data as dataclasses. But I’m missing...

    Hey Tiddlers, I would like some advice, I want to get better at designing programs.

    I’m writing python.
    I write pure functions without side effects.
    I model my data as dataclasses.

    But I’m missing a sense of taste or a nose for design (regardless of language) so I end up writing quite procedural code like:

    Import functions 
    
    Main():
    
    Declare some constants
    
    A = load_data(filepath)
    B = getsubset(A)
    C = calculate_thing(B)
    
    #sideeffect
    Write_C_to_file(C)
    

    I don’t like any of the code I write and generally think it’s bad even if it’s correct, passes a an autoformatter and linter check, and static type check, and I can write passing tests for it.

    2 votes
    1. jmp
      Link Parent
      What you described doesn't look too bad. So without knowing more details, it's hard (for me, at least) to see how to make the design better. Maybe just a couple of thoughts: As others have pointed...

      What you described doesn't look too bad. So without knowing more details, it's hard (for me, at least) to see how to make the design better. Maybe just a couple of thoughts:

      As others have pointed out, Python isn't necessarily well equipped for functional programming. This may be why something about your code feels off for you. When you start using things like immutable data structures and pure functions, you stray further away from object-oriented paradigm and more towards functional paradigm.

      In the OO paradigm, what you would probably prefer is rich domain models that encapsulate the behavior and state (if it exists) for that model. For example, in your case B could be modeled as a class with a calculate_thing method as opposed to a free function. What you would probably also do is separate the file reading and writing part to its own class. So if the persistence format or logic changes, it can be easily swapped or modified in one place.

      In the functional paradigm, you would do something similar to your example instead. Now I suspect it feels a bit off because the data and behavior are separated, and the language doesn't really encourage or support such programming style in any particular way. In many ways, it resembles the more traditional procedural paradigm. In languages like Clojure, it's more natural to write code in this way: If everything is an immutable list or map, you can use any functions that operate on lists or maps (many of which the language / standard library already provides for you), and combine and chain them together in all sorts of ways.

      5 votes
    2. scottc
      Link Parent
      What you have is what most of our Python programs look like at my job. We use Python to process large sets of data, and we typically split functions into data access, engine, and controllers....

      What you have is what most of our Python programs look like at my job. We use Python to process large sets of data, and we typically split functions into data access, engine, and controllers. There's no reason to get bogged down in object oriented design in Python, which can be hard to get used to if you started in the OO world.

      I would be happy with your design if I saw it in a review. The most important thing for maintainable code is separation of concerns and encapsulation, which it looks like you have.

      The other side of my job is embedded C, so we think very procedurally, which influences our Python.

      3 votes
    3. r-tae
      Link Parent
      In my experience, this is exactly what Python scripts naturally look like. I don't think there's much wrong with it, although if you tend to repeat parts of that often enough you could consider...

      In my experience, this is exactly what Python scripts naturally look like. I don't think there's much wrong with it, although if you tend to repeat parts of that often enough you could consider writing your own utility library.

      3 votes
    4. bytesmythe
      Link Parent
      There are a couple of things you might be interested in checking out: A pure functional language, like Haskell. This would force you to handle your side effects in a clean way, but the languages...

      There are a couple of things you might be interested in checking out:

      1. A pure functional language, like Haskell. This would force you to handle your side effects in a clean way, but the languages have a reputation for being academic or difficult to learn.

      2. Barring that, maybe try a language that lends itself more readily to that style of programming, but without being quite as restrictive as a pure functional language. I would suggest something like Elixir or maybe Racket.

      1 vote
    5. Johz
      Link Parent
      I don't think that's particularly bad. Conceptually, it looks really readable to me. I think the thing that would potentially make the data flow more obvious is the pipe operator, which is an...

      I don't think that's particularly bad. Conceptually, it looks really readable to me.

      I think the thing that would potentially make the data flow more obvious is the pipe operator, which is an operator like |> or %>% (depending on the language) that allows you to describe more of a pipeline for your data. The classic example is a UNIX shell pipeline, where you take some data from one command and pipe it into another command, and pipe the output of that command into another command, and so on.

      For example, your code would look like this:

      c = load_data(filepath)
          |> get_subset
          |> calculate_thing
      ...
      

      Unfortunately, Python doesn't have the pipe operator, so this isn't going to work. But I think it's interesting (and hopefully encouraging for you) to see how much the pipeline version looks like the imperative version - both are essentially a series of commands, one after another, that process the data created by the previous line. What you're essentially doing here is manually doing something that might be only slightly clearer in a purely functional language.

      The other thing you could have a look at if you're really interested in diving into the full functional rabbit hole is point free programming and the compose function. The compose function is a function that takes two other functions and essentially pipes them together, and returns a new function that does both of those things. So if I've got a function int which turns a string into a number, and a function greater_than_zero that returns true if a number is greater than zero, I can combine them together:

      program = compose(int, greater_than_zero)
      
      text: str = input()
      program(text) # returns a boolean
      

      This is sometimes called point-free programming, where "point" refers to the arguments to the functions. (See how we never look at the arguments to int or greater_than_zero, we just glue them together into a larger function.) Theoretically, you can build whole programs in this style.

      That said, Python is not the best language for this sort of programming. It lacks a lot of the important primitives, as well as things like implicit currying that make it easier to use. The code is often harder to read if you're not familiar with it, so I would be careful about doing anything too complicated if you want your colleagues to like you! But composing pipelines together is probably a good example of where it could work well in Python, so maybe give it a go there and see if it's helpful?

      1 vote
  3. [4]
    Leftbones
    Link
    I've been writing a cellular automata sand simulation in C#, lately I've been trying to get multithreading to work. The world, which is one giant 2D array of cells, is split into chunks. The...

    I've been writing a cellular automata sand simulation in C#, lately I've been trying to get multithreading to work. The world, which is one giant 2D array of cells, is split into chunks. The chunks are processed in an order such that no two adjacent chunks are processed at the same time. Yet, I'm running into race conditions between two chunks that are unable to interact with each other.

    From what I've been reading, it should be possible for two separate threads to read and write to the same 2D array at the same time, as long as they aren't reading/writing the same part, which in this case they never are.

    Any ideas? Debugging race conditions is proving to be extremely difficult.

    2 votes
    1. [3]
      Trauma
      Link Parent
      I'm not familiar enough with the C# memory model, but are you sure that you really are waiting for a chunk to be finished and safely tucked away before another thread (behind another CPU cache)...

      I'm not familiar enough with the C# memory model, but are you sure that you really are waiting for a chunk to be finished and safely tucked away before another thread (behind another CPU cache) gets to muck with it? How are you synchronizing this? (Because a normal work queue/thread pool won't do it). Maybe visualizing which cells are being worked on and slowing it down would help, or recording cpu instruction clock for each thread/chunk/start/stop and playing it back if the above solves the race by debug mode, as is often the case. Remember that without volatile the optimizer has a lot of leeway when rearranging your instructions/memory accesses.

      1. [2]
        Leftbones
        Link Parent
        I actually did figure out what was wrong. It turned out that I was processing the individual cells in parallel, rather than the chunks. I also found out with someone else's help that I was using a...

        I actually did figure out what was wrong. It turned out that I was processing the individual cells in parallel, rather than the chunks. I also found out with someone else's help that I was using a single instance of Random for everything, which is not thread safe. So, adding individual Random instances per chunk and fixing the aforementioned parallel issue fixed my race conditions! The performance gain wasn't as massive as I was hoping, but it's still there, and I'm sure it can be increased further once I'm ready to put more time into it.

        1. Trauma
          Link Parent
          Glad to hear it's working. Race conditions can really ruin your day. WRT performance: your chunks as they lie in the array are probably all over the place and not aligned, which could lead to a...

          Glad to hear it's working. Race conditions can really ruin your day.

          WRT performance: your chunks as they lie in the array are probably all over the place and not aligned, which could lead to a lot of cache lines bouncing around between cores.

          1 vote
  4. Handshape
    Link
    Older dev here with a few decades of experience. I did okay keeping my skills rounded from the mid 90's through to about '20. My shop tried to push me away from the keyboard and into a management...

    Older dev here with a few decades of experience. I did okay keeping my skills rounded from the mid 90's through to about '20. My shop tried to push me away from the keyboard and into a management role, but I remember what it was like working for "that guy" and want to avoid becoming him.

    Where I left off was about when every other concern started trying to shove itself into DevOps pipelines, and people were starting to sit up and take notice of the supply-chain mess happening in the various public repos. I also remember that a lot of the big-name API providers were starting to get pretty brazen about making breaking changes to their services with very little notice.

    What have I missed in the last three years or so?

    2 votes
  5. Wes
    Link
    Question for any web devs using the new @container queries. I've been making great use of these for responsive design. The dynamic sizing means I can easily use something like font-size:...

    Question for any web devs using the new @container queries.

    I've been making great use of these for responsive design. The dynamic sizing means I can easily use something like font-size: clamp(0.9em, 5cqw, 1em) and get predictable results. What I find weird though is that to access container units, I need to place the rule in a @container query. Easy enough, but what if no condition is needed?

    I'm ending up with a lot of @container (min-width: 0) littered in my code, which feels a bit unsanitary. Is there any way to use these without a conditional?

  6. [5]
    joshbuddy
    Link
    I've been busy building a framework for replicating SQLite databases in a p2p e2ee fashion, where different clients can have different versions of schemas. I'm hoping to make it easy to build...

    I've been busy building a framework for replicating SQLite databases in a p2p e2ee fashion, where different clients can have different versions of schemas. I'm hoping to make it easy to build privacy-preserving offline first apps.

    Is this sort of framework interesting to anyone? What sort of features would you need to make it really appealing?

    1. [4]
      Trauma
      Link Parent
      That certainly sounds interesting, I was looking for something like this recently to make serverless apps for small group sharing of simple stuff like chores, low critical finances and shopping...

      That certainly sounds interesting, I was looking for something like this recently to make serverless apps for small group sharing of simple stuff like chores, low critical finances and shopping lists. Supporting different schema versions is ambitious, though. I guess you require primary keys on everything?

      1. [3]
        joshbuddy
        Link Parent
        I was actually approaching it more like an EAV that you pivot into normal sql tables. I have a pretty good poc working for that actually. I recently figured out how you can use partial indexes in...

        I was actually approaching it more like an EAV that you pivot into normal sql tables. I have a pretty good poc working for that actually. I recently figured out how you can use partial indexes in sqlite to support an EAV table and have a view of that table that looks normal, so no need to copy data to achieve the pivot.

        I build a little proof-of-concept todo list/chat app on top of the framework to demo what can be done. Happy to share the code to both the framework and poc if that sounds interesting to you.

        1. [2]
          Trauma
          Link Parent
          Incidentally one of the things I was looking for an excuse to use :). Well, share away, I'm sure I'm not the only one who will risk a look.

          partial indexes in sqlite

          Incidentally one of the things I was looking for an excuse to use :). Well, share away, I'm sure I'm not the only one who will risk a look.

          1. joshbuddy
            Link Parent
            They are really nifty, I was super happy to find a use for them. Here is the framework itself https://github.com/meow-io/go-slick Here is the bit where it makes the view...

            They are really nifty, I was super happy to find a use for them.

            Here is the framework itself https://github.com/meow-io/go-slick
            Here is the bit where it makes the view https://github.com/meow-io/go-slick/blob/main/data/eav/eav.go#L347
            And finally, here is the sample app https://github.com/meow-io/roost

            This is my first go project, so, I'm sure I'm doing lots of non-idiomatic things here (which I'm happy for any feedback) :)