kamray23
Joined 5 years ago
Joined 5 years ago
I do agree with the "fork and make it better for you", but I also think it's common courtesy to throw up issues for the bugs or missing features you encounter, as well as pull requests. If for no other reason then as "prototypes" or "quick fixes" that others can cherry-pick into their own forks. They may get rejected, they may get closed, but you still don't have to sit there arguing about it since you have your own version. From a slightly Kantian angle you have your working version and you've now fulfilled your social duty by offering solutions to problems. You've got no need to campaign for the solutions if they get rejected.
It's virtuous and you get to ignore the github flame wars. There's really no downside beyond taking 5 minutes to be nice and at least put your solution out there. Also fulfills your reciprocal legal duty under LGPL and such.
It's like the classic "little lambda thing" that someone posts on HN and finds a $2 million invoice in their inbox a couple weeks later. Except instead of going viral your achievements get mulched by AI.
Stronger concrete requires more stress to cause it to fail, and as such it takes more force to break it. There is logically more energy because of the higher force, so more energy gets released.
However as I mentioned, since it is not true that most people can read FP code, I mostly avoid using it. The example comes from my solution to AoC2023's Day 3, "Gear Ratios", which is just about the only thing I use Haskell for.
That doesn't mean that using it doesn't have practical applications, since being used to multiple paradigms opens you up to unconventional solutions. I've recently sped up a MATLAB function ~100x through using a more functional style to manipulate memory more efficiently. Async/await, certain styles of modern iterator manipulation and generators escaped F#, CLU and others into C# and from there into the world at large specifically because Microsoft programmers saw a problem they had had a solution for in previous functional projects. So it's not all useless.
For the record, a more imperative version could be written as
symbols = [ imagine there's stuff here ]
gears = []
for (symbol, coord) in symbols:
if symbol == '*':
ns = neighbouringNumbers(coord)
if len(ns) == 2:
gears.append(ns)
or in Python's functional-inspired notation which directly mirrors what's happening in the Haskell code gears = [ neighbouringNumbers(coord)
for symbol,coord in symbols
if symbol == '*' and len(neighbouringNumbers(coord)) == 2 ]
though that requires an unnecessary extra call to neighbouringNumbers, which you could solve with a walrus op but I can't remember how to do that. I also changed the entire pair being passed to neighbouringNumbers (which was convenient in Haskell) to only the coordinate that is required (which is convenient in Python).Personally I just find nowadays that having to comprehend "it collects neighbour-pairs from '*' symbols" from the imperative code harder than having that be the thing that is actually written down.
As what their owner wants them to be, with data transmission into the brain and individually addressable neurons, they're leagues off from a functional product. Extracting and interpreting brain signals is, while not simple, well-known and well-practiced. The other direction is practically unexplored and the most we normally do is poke around with a bit of electricity and hope it makes the brain work better. To move data from a computer into the brain would be a total revolution. Needless to say, their current product does not do this, and they've shown zero development to this end. Which kind of makes it feel like they're hoodwinking Musk to develop actually useful medical devices instead of playing into his naive technocratic futurism. That just means they know what they're doing even more strongly than what their other actions have already shown.
gears = filter ((==2) . length)
. map (neighbouringNumbers numbers)
$ filter ((=='*') . fst) symbols
which without currying would have to look like gears = (\xs -> filter ((\x -> x == 2) . length) xs)
. (\xs -> map (\x -> neighbouringNumbers numbers x) xs)
$ filter (\(c,_) -> c == '*') symbols
It just makes partial application a lot easier, especially when this kind of code pops up all over the place.Worse perhaps are all types of proximity sensors, because you can only trust them when they go off, and even then not always. Most cars get dirt on them, snow on them, rain on them and that tends to mess with proximity sensing enough to either disable the sensors or cause them to go off randomly. I don't think anyone has ever yet trusted the blind spot sensors on their mirrors to do a lane change, only aborted one because of them. Such non-camera sensors would fix almost nothing because at best they would sometimes cause people to reconsider swerving into a motorcyclist, and even then they usually go off way too late to prevent misfires while driving normally.
These are great features when they work but overengineering around fundamental design problems seems to me to only put people too much at ease in their cars and make bad driver behaviour worse, because why spin your head around to check when you can just not do that and stare at the little screen or trust your array of easily fooled sensors to do safety in your place. I think solutions like finding alternative pillar configurations, creating long or short enough front side windows for you to see back, harsher driver's license testing with longer required study periods and in cases where you can't do anything else such as some pickups just doing what semis do and having several well-aligned mirrors instead of one set of nice-looking ones would be a lot safer in the end.
As well as getting people who can't drive for shit off the road. That's sort of included in driver's license requirements but there's surely some other methods for it that I have not mentioned.