I never knew who I was. I still don’t know who I am. It doesn’t matter anyway.

  • 0 Posts
  • 4 Comments
Joined 19 days ago
cake
Cake day: February 14th, 2026

help-circle
  • @yogthos@lemmy.ml @programming@lemmy.ml

    The x86css didn’t work because CSS @function rules aren’t yet implemented on Firefox (by extension, Waterfox). I’m not gonna spin up the Chromium.

    Then I tried other projects from this lyra.horse website, I tried the CSS clicker (a clicker game which uses no JS, just CSS and HTML). It’s very interesting. There are a few glitches (e.g. the “Name your website:” should behave like input[type='text'] but actually behaves like textarea, thus allowing newlines where the semantic (a title) expects none; IIRC, there are CSS properties allowing a [contenteditable] element to restrict the input to an one-line text) but interesting nonetheless.

    The only problem, besides the limited support for certain state-of-the-art features across browser engines, is the fact that this “CSS-oriented functional programming” ends up requiring more processing power than JS does, because JS has optimizations that CSS often lack.

    Don’t get me wrong: it’s really interesting, and I’m quite fond of unorthodox approaches to programming. I myself once used nodemon (a live-reloading CLI tool intended for Node.js but also usable for other programming languages) to compile and run an Assembly (GNU Assembly) Linux program as the code was being edited, and I also used the same Assembly tool-chain to code a “program” whose compilation result wasn’t an actual runnable program, but a whole, valid BMP (Bitmap) image structure, full with a linear gradient, I achieved this by using compiler macros. This is how much I’m fond of unorthodox programming, so I’m far from being against CSS programming, much to the contrary: it’s awesome!..

    … but this whole approach, using CSS as a whole functional programming language, unfortunately ends up heating my old poor I5-7200U laptop…



  • @bleistift2@sopuli.xyz

    Back when I coded that (it’s been years), I opted for the shortest one-liners possible (I often catch myself doing one-liners and code-golfing for the fun of it), with “n” and “x” meaning respectively “miN” and “maX”. Hence why I also do a call to rand inside the irand, so irand is as shortest as possible.

    As for the bias towards the mid, it’s by design, because ends up quite similar to the central limit theorem:

    > Array.from(Array(10000), _=>irand(0,6)).reduce((p,v)=>({...p, [v]: (p[v]||0)+1}), {})
    {
      '0': 840,
      '1': 1602,
      '2': 1658,
      '3': 1691,
      '4': 1684,
      '5': 1687,
      '6': 838
    }
    

    Notice how both extremities have lower values while the median (3) got the maximum value (1691). I wanted something behaving similarly to how noise often feels like in real world settings (e.g. SDR radio settings, never truly uniform), hence why the “maX” value is inclusive, it’s purposefully meant to, just like the “miN” value is also inclusive, because they need to be inclusive so it gets to appear amidst the samples.

    As a comparison, when I change it to trunc (because floor would behave differently for negative numbers), as in:

    > irand = (n, x) => Math.trunc(rand(n, x))
    [Function: irand]
    > Array.from(Array(10000), _=>irand(0,6)).reduce((p,v)=>({...p, [v]: (p[v]||0)+1}), {})
    { '0': 1684, '1': 1659, '2': 1685, '3': 1668, '4': 1676, '5': 1628 }
    

    …then the sample gets too annoyingly uniform, not even to say about how max (the 6) ends up missing from the samples (thus requiring a x+1 whenever the max value is intended to be inclusive). This may be the best distribution for certain scenarios where uniform randomness is expected, but this doesn’t feel… natural.

    That’s also why I implemented this JS flavour in a personal Ruby gem (utils.rb) because Ruby got this annoyingly uniform distribution with its native Random.rand (again, useful sometimes, but not exactly natural):

    irb(main):041:0> 10000.times.map{Random.rand(0..6)}.tally.sort{|a,b|a[0]<=>b[0]}.to_h
    => {0=>1431, 1=>1449, 2=>1395, 3=>1435, 4=>1411, 5=>1465, 6=>1414}
    irb(main):042:0> def rand(n,x) = Kernel::rand()*(x-n)+n
    => :rand
    irb(main):043:0> def irand(n,x) = rand(n,x).round
    => :irand
    irb(main):044:0> 10000.times.map{irand(0,6)}.tally.sort{|a,b|a[0]<=>b[0]}.to_h
    => {0=>892, 1=>1612, 2=>1744, 3=>1643, 4=>1592, 5=>1708, 6=>809}
    

    See how my Ruby’s irand implementation behaves exactly as my JS’s irand do: with this more natural bias towards the middle.

    As for the possibility to do irand(x), because the use case often involves having a well-defined range instead of a maximum target value (minimum value isn’t even always zero, but something arbitrary such as e.g. irand(65,65+25) for generating codepoints for alphabet letters), this is why it’s not overloaded so to default n to zero.