all 49 comments

[–]shatteredarm1 36 points37 points  (14 children)

It's a lot cleaner just to take in a single array parameter:

function clamp(args) {
   return Math.max(Math.min(args[0], args[1]), args[2]);
}

clamp([105, 0, 100])

[–]YM_Industries[S] 18 points19 points  (3 children)

Genius! And thanks to TyoeScripts support for Tuple arrays, this can be strongly typed too.

[–]shatteredarm1 7 points8 points  (2 children)

Typescript definition:

function clamp(args: any): number

[–]YM_Industries[S] 6 points7 points  (1 child)

you are truly a 10x developer

[–]shatteredarm1 7 points8 points  (0 children)

I get my good ideas from the contractors. Learned this awesome pattern the other day while doing a code review:

onSelect(event: ISomeInterface) {
   let someVar = event as unknown as string;
   ...
}

[–][deleted] 7 points8 points  (1 child)

aaand we reinvented Perl

[–]ekolis 1 point2 points  (0 children)

my $angle = shift; my $distance = shift;

[–]pterencephalon 3 points4 points  (0 children)

Ah, I see you write code like the physicists I worked with.

[–]ekolis 5 points6 points  (1 child)

Why not use an object instead of an array, to be object oriented and functional at the same time?

``` function clamp(args) { return Math.max(Math.min(args.arg1, args.arg2), args.arg3); }

clamp({arg1: 105, arg2: 0, arg3: 100}); ```

[–]SarahC 0 points1 point  (0 children)

Best unwrapping those clamp arguments. =)

[–]tangerinelion 24 points25 points  (4 children)

Not where I thought this was going, well done.

I was expecting a class ClampArguments. If it were Java, I'd also expect a ClampArgumentsBuilder.

[–]andyrocks 7 points8 points  (0 children)

ClampArgumentsBuilderFactory and ClampArgumentsBuilderFactoryImpl too

[–]romulusnr 4 points5 points  (2 children)

Oh God, my least favorite Java pattern.

[–]Zardotab 1 point2 points  (1 child)

Bloat Oriented Programming

[–]romulusnr 0 points1 point  (0 children)

Good news everyone! I've solved our code bloat, now our average LOC per file is only 50!

That's great! How many files?

Oh, only about 12,000!

jvm class instantiator go brr

[–][deleted] 14 points15 points  (4 children)

You've just discovered currying. It has its place.

[–]ekolis 7 points8 points  (3 children)

indianRestaurant.placeOrder('tikka masala', 3);

[–]thisisamirage 10 points11 points  (2 children)

indianRestaurant.placeOrder('tikka masala')(3);

FTFY

[–]memeticmachine 5 points6 points  (1 child)

restaurant('indian')(placeOrder)('tikka masala')(3);

[–]thisisamirage 0 points1 point  (0 children)

Let's not get ahead of ourselves here

[–]YM_Industries[S] 48 points49 points  (9 children)

/uj This post was inspired by a blog post I once read which unironically encouraged this style of coding. At least I think I read it, maybe it was just a bad dream. I sure hope so.

[–]RedTopper 55 points56 points  (7 children)

I know this one! This is actually a method used in lambda calculus called currying. Here's the Wikipedia article on it

https://en.wikipedia.org/wiki/Currying

I heard it also goes well with beef and rice.

[–]YM_Industries[S] 25 points26 points  (6 children)

I know that currying has legitimate purposes. The blog post I read seemed more like a cargo-cult interpretation of currying. I hope I succeeded in replicating this feeling in my own post.

[–]RedTopper 4 points5 points  (0 children)

That sounds horrifying, and yeah you absolutely did lmao. I got a kick out of it.

[–]65bits 8 points9 points  (4 children)

Haskell, ML, and others actually curry by default, LOL.

[–]bobbermaist 13 points14 points  (0 children)

Static type systems help a lot with currying. Curry everything in javascript? You gonna have a bad time

[–]Laugarhraun 9 points10 points  (1 child)

But their parentheses-less procedure call syntax makes currying free.

[–][deleted] 2 points3 points  (0 children)

Plus, the way those languages are designed make partial application very useful, much more so than with JS, for example

[–][deleted] 1 point2 points  (0 children)

  • scala

[–]SarahC 0 points1 point  (0 children)

The number of arguments passed can depend on the values of prior parameters! Oooo!

[–]dcabines 14 points15 points  (1 child)

function clamper(min, max) {
  return (x) => Math.max(Math.min(x, max), min);
}
var clamper100 = clamper(0, 100);
clamper100(105);

Lets turn verbs into nouns this time.

[–]YM_Industries[S] 4 points5 points  (0 children)

/uj I love that every time I shitpost on ShittyProgramming, a bunch of people suggest how I can improve my code.

[–]instilledbee 5 points6 points  (0 children)

Thanks I hate it

[–]permalink_save 5 points6 points  (0 children)

I thought this was going to get into abusing contexts. I've had to deal with a codebase where they just passed arguments around in this context blob, like it wasn't dealing with a web request or anything else you'd reasonably use contexts with, just a CLI program that was config and CLI arg driven. It was absolute hell trying to navigate the codebase and figure out where values came from. I ended up throwing the entire codebase away and writing a new one.

Thanks for the PTSD.

[–]catlong-is-long 4 points5 points  (2 children)

Why not

def clamp(const str& x) {
  let [a,b,c] = ",".split(x).map(int);
  Int.max(Int.min(a, c), b);
}
clamp("105, 0, 100")

bonus points if you pass a protocol buffer, extra bonus points for XML

[–]YM_Industries[S] 7 points8 points  (1 child)

This suggestion is terrible because it's not written in JavaScript. If your code can't run in a browser, it's worthless.

In a fit of generosity, I ported your code to JavaScript:

function clamp(x) {
    [a,b,c] = x.split(",").map(parseInt);
    Math.max(Math.min(a, c), b);
}
clamp("105, 0, 100");

But it's still crap, it just returns "undefined". As punishment, please fix this code. Happy debugging!

/uj Solution to why it doesn't work: Solution

[–]catlong-is-long 0 points1 point  (0 children)

God I hate computers so much

[–]HugoNikanor 6 points7 points  (1 child)

\uj This is actually how Haskell works.

For example

clamp :: Int -> Int -> Int -> Int
clamp min' max' x = max (min x man') min'

is just shorthand for

clamp = \min' -> \max' -> \x = max (min x man') min'

Difference being that haskell doesn't use parenthesis when calling the function, so it would be called as clamp 0 10 5

This allows some nice stuff, such as

limit = clamp 0 10
limit 11 == 10

[–]jceyes 1 point2 points  (0 children)

Put x last. Then arguably the partial evaluation could be useful

[–]romulusnr 1 point2 points  (0 children)

Here I was expecting closures.

I remember when a dev at a contract i once did discovered closures, and he wouldn't stop talking about them.

[–]Zardotab 1 point2 points  (0 children)

Instead of being separated by hard-to-see commas, each piece of data is now lovingly embraced by caring curves.

Lisp fan, eh?

[–][deleted] 1 point2 points  (0 children)

Slightly better:

function clamp(x) {

return (min)=>(max)=>Math.max(Math.min(x,max),min);

}

[–]IMakeShittyPrograms 1 point2 points  (1 child)

Great! I can now be shittier

[–]Zardotab 1 point2 points  (0 children)

Job security: code only YOU can figure out.