Programming thread

  • 🐕 I am attempting to get the site runnning as fast as possible. If you are experiencing slow page load times, please report it.
Just use whichever tool you're comfortable with. Emacs has OG vibes but you're not obligated to waste brain cycles on it.
The Clojure talks are great. 4clojure has been revived on 4ever clojure.
To get started, there are several examples of real world applications flying around, start with Sean Corefield's user manager example if you want to deal with backend/webdev, or look at cljfx if you like UI and personal computing software.
In terms of books, there are a couple written by Alex Miller, besides which I wouldn't bother with other books at the time, as they're not essential. Use the official cheatsheet, it's a godsend, use apropors and use find-doc. Learn to work with the REPL.
Do join the clojurians slack. That's where most discussion and support are.
Closing words - some "anti patterns", or just stuff you will forget and get wrong at the beginning
- don't do side effects in lazy contexts
- `for` is a list comprehension, not a for loop
- `for` is lazy, don't do side effects in it
- same goes for `pmap`
- you know what, just figure it out without `for`, for now
- you don't need refs
- you really don't need refs
- you probably don't need an atom, unless you want to share data between multiple threads
- immutability will trip you. You will write something like (assoc m k v) and not use the return value, and be surprised the map doesn't contain the key you expected
- don't count on transients to change in-place. Always work with return values from functions.

Some positive advice
- use the fucking REPL
- use clj-kondo
- use something to format your code like zprint because it will probably look like ass before you have a sense of style
- go over the cheat sheet and the style guide (thanks Bozhidar!)
- it doesn't really matter if you start with lein or cli tools, chill
- drink some Cider, it's good for you
 
I had a very frustrating experience in C++ recently. C++ allows for type coercion of function parameters, so if you pass an int or comparable type to a function that was defined to accept a char, C++ will do the conversion and try to run the function with the type coerced parameter. After this experience I think this is a horrible idea or feature.

I been working on doing an algorithm for a lexer. Very simple at this point; just getting a good concept of the algorithm before adding abstraction and more features the lexer can handle. This is really early days for the whole project, so it will seem very basic. I take the last implementation I got working, copy it, and then start to add small changes to make the implementation more abstract. I have 3 functions that all do the same thing, but slightly differently. I mention this, but it's not the point it's just background.

I notice that one of the functions does not work the way it should be and it's an outlier for the other 2. `is_whitespace' is called is each of the 3 functions the same way.
Code:
size_t x; // which is not actually initialized here
          // and is the pointer in a for loop.
while (is_whitespace(x)) {
  // do some stuff
}
In only one does it create errant output. I have 2 versions with the same usage working find, so what is wrong? The function skips over the the letter `a' if it's followed buy a space. Turns out I don-goofed and x is the wrong variable for `is_whitespace', which is defined:
Code:
 bool is_whitespace(char space)
{
  switch (space) {
  case '\n':
  case '\t':
  case ' ':
    return true;
  }
  return false;
}
Perfectly good function dose what it should. `space' is converted to an int and the chars are matched like ints. No problem here. Case statements are usually considered to be not so safe or turn into retarded programs, but in this limited usage it does the job.

After going though and adding debugging to every variable in the function, I then see that it's this while loop causing it and only in this one instance of it's use; the same construction is used in all functions, but only works wrong in this one function. But I knew this, I made `is_whilespace' for char not size_t. A day ago when I was working on this, the compiler should have caught this miss use of x with `is_whitespace' then. It's just luck that this error doesn't come up in all three functions. But that's why this is a horrible C++ feature. It should have been an error the first time I tried to use `is_whitespace' wrongly with the wrong type.

I'm wondering if I shouldn't write the C++ Committee and tell them to drop function parameter type coercion because it causes problems like this story. Previously I hand thought that undefined behaviour was really only in problems with pointers, but it's just everywhere.
 
Last edited:
Case statements are usually considered to be not so safe or turn into retarded programs, but in this limited usage it does the job.
[citation needed]
I'm wondering if I shouldn't write the C++ Committee and tell them to drop function parameter type coercion because it causes problems like this story. Previously I hand thought that undefined behaviour was really only in problems with pointers, but it's just everywhere.
Not gonna fly due to C and legacy compatibility. The only way out is through, meaning: define your own types.
 
  • Like
Reactions: ditto
What would people suggest doing in order to get good at LeetCode? I'm getting pretty confident with the medium level problems but all of that falls apart during technical interviews.
 
I read this, and and this ("Clean Code"(p37-39) by Robert Martin) found it a pretty interesting read, even though I don't program in Java because I am neither a transvestite, nor gay. but sometimes you have to see how the other side lives to know how good you have it.
Python:
import solution

You can look at the deficiencies of the switch statement in crappy languages and come to two different solutions: avoid it completely and use something else, or make a different language construct that does the same thing but better. The OOP people went with the former: use polymorphism with subclasses. The functional people went with structural pattern matching resting on a more expressive type system.

Personally I think the functional people had the right idea. There's just way less boilerplate and ceremony. See also this blogpost about the overhyped evils of the switch statement and the dubious OOP remedies for it.

PS Clean Code is trash
 
Last edited:
You can look at the deficiencies of the switch statement in crappy languages and come to two different solutions: avoid it completely and use something else, or make a different language construct that does the same thing but better. The OOP people went with the former: use polymorphism with subclasses. The functional people went with structural pattern matching resting on a more expressive type system.

Personally I think the functional people had the right idea. There's just way less boilerplate and ceremony. See also this blogpost about the overhyped evils of the switch statement and the dubious OOP remedies for it.

PS Clean Code is trash
Interfaces aren't bad in and of themselves. I think OOP gets it wrong with subclassing and inheritance, otherwise they're just more open than cases. They fail where you can't extend your new interface to an existing object, which is where you need mixins or witnesses. (re the expression problem).
I generally prefer polymorphism to pattern matching matching. Just keep the damn interfaces small. A single method in an interface is enough. Sometimes it's even too much.
 
  • Agree
Reactions: Anstiv
The relational model is one thing. That's modelling and makes people literally square the circle. Most shit in life is not relations just like most shit in life is not objects. So the data model is a fuck and what we really need is graphs. BUT NEVERMIND THAT, which absolute monkey designed a language in plain text first and left specification down to the fucking implementer? There's even no execution model. The query engine and indices are opaque. Billions of dollars in damages because of that retarded decision.
SQL injection shouldn't have been an issue to begin with.
Sorry, what? Execution model for declarative language of relational algebra? How is that supposed to work?
And what SQL injection is to do with SQL itself? Why it's SQL fault that square-headed web-developers generating SQL verbatim and not using existing facilities for transfer data into queries? Billions of dollars in damages because business cutting expanses on developers and hiring absolute retards that cannot comprehend basic programming concepts.
 
And what SQL injection is to do with SQL itself? Why it's SQL fault that square-headed web-developers generating SQL verbatim and not using existing facilities for transfer data into queries? Billions of dollars in damages because business cutting expanses on developers and hiring absolute retards that cannot comprehend basic programming concepts.
Even SQL DBs for Indians (Oracle) have had prepared statements since the mid 90s. The refusal of Indians to use them in web programming, which would be sensible for performance reasons let alone security, is not on SQL. It's on Indians.
 
You've never herd of Duff's Device?
Also I've seen stuff like this:
Code:
switch(thing) {
while (nz != 5) { // a while loop in a switch starts
case 10:
case 11:
rk = 3;
} // a while loop in a switch ends
case 5:
rk = 5;
default:
return -1;
}
I was show this once. In old compilers this used to work. I bet preventing constructions like above switch-case also broke compatibility. Another thing to consider is that if you find a switch-case where ever case breaks, it would probably be clearer to use if-else. Often programmer like the aesthetic of switch-case, it having a clearer left thing becomes right thing expression. The intent of the program is better communicated when you have ever case break when you use a if-else statements.
define your own types
If I set out to write all my own types I might as well write a new programming language. It's not feasible to rewrite the entire language just because the original types in the language are not strongly enough typed to work correctly. If this were the strategy chosen I'd end up with a wrapper for every type I use including int and size_t. `std::string' would be the first to get redefined with member functions for searching, splitting, and sub-stringing. It is not wrong to create wrapper types, but if you have to start doing it for basic things like strings and ints you end up with an inefficient source tree; you will need these wrappers because they are so basic in every project you write. Just writing a abstraction wrapper type for everything would be too defuse and ultimately inefficient.

You can look at the deficiencies of the switch statement in crappy languages and come to two different solutions: avoid it completely and use something else, or make a different language construct that does the same thing but better. The OOP people went with the former: use polymorphism with subclasses. The functional people went with structural pattern matching resting on a more expressive type system.

Personally I think the functional people had the right idea. There's just way less boilerplate and ceremony. See also this blogpost about the overhyped evils of the switch statement and the dubious OOP remedies for it.

PS Clean Code is trash
Totally agree. Match is much better then switch-case. I think Scala and Ada both have switch statements that work like match, where each case breaks. So, it's not an outlier to realised that what feels good to write should also be what better expresses the program. The sad part is I've never seen anyone use a switch-case properly to get the most utility out of it. You can do like a hourly schedule with the cases as hours and have over lap, having the same thing done at consecutive hours. This is probably used this way, because it's not dynamic enough to be useful as a schedule. Schedules need times accurate at least to seconds and need to be change more often then the program is complied, so it becomes more logical not to uses a switch-case.
 
Last edited:
You've never herd of Duff's Device?
Sure I did, but it does not answer the question.
Also I've seen stuff like this:
People write horrendous code, more news at eleven.

That says fuck-all about switch statement, just as quoting Dijkstra's article in relation to goto (see also: where does my nickname COME FROM).
If I set out to write all my own types I might as well write a new programming language.
Hey, don't blame me. I explicitly stated some pages ago that even C gives you enough rope to either hang yourself or define your own abstractions.
 
  • Mad at the Internet
Reactions: Anstiv
You're going to make fun of me for this solution, but psychologically I want to think of `x' as the pointer from the for loop and as the character that the pointer's index is returns from string index. So, while technically wrong, it feels good to think `x' is a size_t in the for loop and `x' is the char in the string, while both being the same x. What I need is a different x. An `x' that is not the index position, but the result of the index, and is a single ident. While unnecessary it feels better to write mystring[x] as a single ident. So, I created a lambda that captures `x' and mystring so that the lambda can be a single ident and return the char at index.
Code:
#include <functional>
#include <iostream>
#include <string>

int main()
{
  std::string mystring = "Oh boy, a string!";
  for (size_t x = 0; x < mystring.length(); x++)
    {
      function<char()> current = [&x, &mystirng]() {
        return mystring[x];
      };
      std::cout << current();
    }
  std::cout << std::endl;
  return 0;
}
The stupid thing is that this isn't wrong. A comparable abstraction could provide,
Code:
struct ThingA {
  string thestring;
  size_t index;
  void next();
  size_t position();
  char current();
}
It's by no means revolutionary, but sometimes there does come a need to decompose a for loop like this. The above approch is very similar to the last time I self-harmed by writing a lexer. Then I was in a language without for loops with pointer count and with proper interfaces. I'm stuck with C\+?+ because of "it's legacy comparable" and has to use the same libraries as the old C system this new one is replacing. Not that you care, but this is the same project I've been working on since May.
 
Last edited:
You're going to make fun of me for this solution,
Yes.
but psychologically I want to think of `x' as the pointer from the for loop and as the character that the pointer's index is returns from string index.
I don't understand.
So, while technically wrong, it feels good to think [...]
[emphasis mine] There's your problem.

I am really not understanding what you are trying to do. Are you trying to reinvent iterators?
 
Switch statements are a perfectly fine construct, I generally use them to create simple state machines, which I think is basically their intended purpose.
I just wish C# would allow typeof and more expressions as switch cases. Had a situation recently where I wanted to limit a type to a specific range of types and the best solution turned out to be a big wall of == and ||. Disappointing!

Look at these filthy fucking subhumans
1631649966962.png
Disgusting. He allocates a whole hashtable, selects a single result, and leaves the rest for the digital janny to pick up.

You're going to make fun of me for this solution, but psychologically I want to think of `x' as the pointer from the for loop and as the character that the pointer's index is returns from string index. So, while technically wrong, it feels good to think `x' is a size_t in the for loop and `x' is the char in the string, while both being the same x. What I need is a different x. An `x' that is not the index position, but the result of the index, and is a single ident. While unnecessary it feels better to write mystring[x] as a single ident. So, I created a lambda that captures `x' and mystring so that the lambda can be a single ident and return the char at index.
Code:
#include <functional>
#include <iostream>
#include <string>

int main()
{
  std::string mystring = "Oh boy, a string!";
  for (size_t x = 0; x < mystring.length(); x++)
    {
      function<char()> current = [&x, &mystirng]() {
        return mystring[x];
      };
      std::cout << current();
    }
  std::cout << std::endl;
  return 0;
}
The stupid thing is that this isn't wrong. A comparable abstraction could provide,
Code:
struct ThingA {
  string thestring;
  size_t index;
  void next();
  size_t position();
  char current();
}
It's by no means revolutionary, but sometimes there does come a need to decompose a for loop like this. The above approch is very similar to the last time I self-harmed by writing a lexer. Then I was in a language without for loops with pointer count and with proper interfaces. I'm stuck with C\+?+ because of "it's legacy comparable" and has to use the same libraries as the old C system this new one is replacing. Not that you care, but this is the same project I've been working on since May.
I totally sympathize with the idea of using indexes in lieu of pointers and the occasional confusions therein, but I have no idea why you're trying to use a lambda there. It doesn't even really look better, it's a one line expression that you're replacing with a three line embedded function. I've done dirty shit like ([&](){/*...*/})() before, but that's only if I want to turn a series of statements into a single expression (useful for initializing a value in place). I don't see the benefit here.


Holy shit now I understand why boomer programmers consistently give unrequested retarded trash advice

Boomer faggot retard Oopsie java code
Java:
package literatePrimes;

import java.util.ArrayList;

public class PrimeGenerator {
  private static int[] primes;
  private static ArrayList<Integer> multiplesOfPrimeFactors;

  protected static int[] generate(int n) {
    primes = new int[n];
    multiplesOfPrimeFactors = new ArrayList<Integer>();
    set2AsFirstPrime();
    checkOddNumbersForSubsequentPrimes();
    return primes;
  }

  private static void set2AsFirstPrime() {
    primes[0] = 2;
    multiplesOfPrimeFactors.add(2);
  }

  private static void checkOddNumbersForSubsequentPrimes() {
    int primeIndex = 1;
    for (int candidate = 3;
         primeIndex < primes.length;
         candidate += 2) {
      if (isPrime(candidate))
        primes[primeIndex++] = candidate;
    }
  }

  private static boolean isPrime(int candidate) {
    if (isLeastRelevantMultipleOfNextLargerPrimeFactor(candidate)) {
      multiplesOfPrimeFactors.add(candidate);
      return false;
    }
    return isNotMultipleOfAnyPreviousPrimeFactor(candidate);
  }

  private static boolean
  isLeastRelevantMultipleOfNextLargerPrimeFactor(int candidate) {
    int nextLargerPrimeFactor = primes[multiplesOfPrimeFactors.size()];
    int leastRelevantMultiple = nextLargerPrimeFactor * nextLargerPrimeFactor;
    return candidate == leastRelevantMultiple;
  }

  private static boolean
  isNotMultipleOfAnyPreviousPrimeFactor(int candidate) {
    for (int n = 1; n < multiplesOfPrimeFactors.size(); n++) {
      if (isMultipleOfNthPrimeFactor(candidate, n))
        return false;
    }
    return true;
  }

  private static boolean
  isMultipleOfNthPrimeFactor(int candidate, int n) {
   return
     candidate == smallestOddNthMultipleNotLessThanCandidate(candidate, n);
  }

  private static int
  smallestOddNthMultipleNotLessThanCandidate(int candidate, int n) {
    int multiple = multiplesOfPrimeFactors.get(n);
    while (multiple < candidate)
      multiple += 2 * primes[n];
    multiplesOfPrimeFactors.set(n, multiple);
    return multiple;
  }
}
Note this fails the basic test of "no side effects" because it silently modifies global variables and not even in a thread safe way! Absolutely mongoloided.

Or me C# code
C#:
/// <summary>
/// Calculate primes inbetween <see cref="min"/> and <see cref="max"/> and output them into <paramref name="output"/>
/// </summary>
public static void CalcPrimes(long max, ICollection<long> output, long min = 2) {
    static void AddPrime(ref ListSlim<long> primes, long prime) {
        static bool IsFactor(in ListSlim<long> primes, long prime) {
            var maxFactor = Math.Sqrt(prime) + 1;

            for (int j = 0; j < primes.Count && primes[j] <= maxFactor; j++) {
                if (prime % primes[j] == 0)
                    return true;
            }
            return false;
        }

        if (!IsFactor(in primes, prime))
            primes.Add(prime);
    }

    if (min < 2)
        throw new ArgumentOutOfRangeException(nameof(min));

    var primes = new ListSlim<long>();

    primes.Add(2);

    long cur = 3;

    for (; cur < min; cur += 2)
        AddPrime(ref primes, cur);

    int startIdx = min <= 2 ? 0 : primes.Count;

    for (; cur < max; cur += 2)
        AddPrime(ref primes, cur);

    for (int i = startIdx; i < primes.Count; i++) {
        output.Add(primes[i]);
    }
}
I'll admit mine isn't the super refined, but I wrote this a while ago for the sole purpose of finding optimal primes for the construction of a hash sequence random walk. If I were to change anything it'd probably be to return the resulting list rather than output it to a parameter.
With 5 individual tables of length 31, 13, 11, 5, and 3 respectively you can create a random walk with an effective length of ~66,000, but which only requires 63 entries to store. Additionally since none of the tables are a factor of two, you can sample the table twice to fill out a dword with random without reducing the effective length of the sequence. All this for the low cost of ~250 bytes.
 

Attachments

  • 1631649932893.png
    1631649932893.png
    21 KB · Views: 40
Code:
#include <functional>
#include <iostream>
#include <string>

int main()
{
  std::string mystring = "Oh boy, a string!";
  for (size_t x = 0; x < mystring.length(); x++)
    {
      function<char()> current = [&x, &mystirng]() {
        return mystring[x];
      };
      std::cout << current();
    }
  std::cout << std::endl;
  return 0;
}
You misspelled &mystirng in the lambda, dude. Normally I wouldn't be such a stickler, but it does kind of make me wonder how such a typo even happens. Did you not compile and run this before sharing? Because the compiler would have told you about the typo.

Or, or: did you not copy-paste at all, and instead did you actually type this code live into the Xenforo code box line-by-line? Because I'll absolutely make fun of you for that.
 
  • Winner
Reactions: Anstiv
You misspelled &mystirng in the lambda, dude. Normally I wouldn't be such a stickler, but it does kind of make me wonder how such a typo even happens. Did you not compile and run this before sharing? Because the compiler would have told you about the typo.

Or, or: did you not copy-paste at all, and instead did you actually type this code live into the Xenforo code box line-by-line? Because I'll absolutely make fun of you for that.
The highest performance code is code which doesn't run at all.
 
Sup y'all. I'm just learning to code and using my phone with the app Mimo. I've ran into this issue.
<html>
<body>
<p>
Mimo
<br>
Vienna, Austria
</p>
</body>
</html>

It wants me to add a line break between the addresses of Mimo and Vienna Austria. I'm fairly certain my code is right I've even tried multiple other choices and it still says I'm messing up, but I don't see where.
 
  • Feels
Reactions: ditto
Sup y'all. I'm just learning to code and using my phone with the app Mimo. I've ran into this issue.
<html>
<body>
<p>
Mimo
<br>
Vienna, Austria
</p>
</body>
</html>

It wants me to add a line break between the addresses of Mimo and Vienna Austria. I'm fairly certain my code is right I've even tried multiple other choices and it still says I'm messing up, but I don't see where.
Try putting a slash in the br tag, like this:
HTML:
<br/>
This is called a self-closing tag, most HTML parsers don't care if you have the slash or not but the one in your app might be stricter. If that doesn't work, try putting "Vienna, Austria" in its own p tag.
 
Try putting a slash in the br tag, like this:
HTML:
<br/>
This is called a self-closing tag, most HTML parsers don't care if you have the slash or not but the one in your app might be stricter. If that doesn't work, try putting "Vienna, Austria" in its own p tag.
Self-closing tags are deprecated and, at best, syntactic sugar. The slash is technically still allowed (on void elements* - anywhere else it is an error), but meaningless. I'd personally discourage using it but it's a possibility that some validator is still expecting you to follow that old standard.

As a general rule it's simply ignored - <br/> is exactly the same as <br>, and <div/> (valid under HTML4) is technically illegal but will be treated exactly the same as <div>... i.e. a subsequent matching </div> is still expected.

The question really isn't clear on what the problem is though. I thought he was saying it was adding a line break when it shouldn't be.

*<br>, <img>, <hr>, etc... these elements cannot have any child nodes
 
Last edited:
Back