> I'm not sure I fully appreciate the distinction you're trying to make here: "currying != partial application". Can you clarify?
Currying is the conversion of an n-ary function into a chain of 1-ary function e.g. `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`.
Partial application is what it says on the tin, it only applies k parameters to the function returning an (n-k) parameters function, without actually running the function.
Currying is one method allowing partial application, but not necessarily the only one, or usually the best fit as it tends to not interact well with features like overloading, default parameters, keyword parameters, …
> In particular I don't know what's meant by "curried" and "uncurried" languages
Languages like Haskell, OCaml, or Elm are "curried" by default: when you define an n-ary function it's really just sugar for a chain of 1-ary functions; and the application of multiple arguments is similarly the implicit application of single arguments multiple times e.g.
map : (a -> b) -> List a -> List b
map f l =
case l of
[] -> []
(h::t) -> (f h) :: (map f t)
can be called as
map fn [1, 2, 3]
or
(map fn) [1, 2, 3]
the semantics are identical, which is not the case in an
uncurried language like Javascript or Python:
map(fn, [1, 2, 3])
and
map(fn)([1, 2, 3])
will behave very differently unless the implementer has taken special steps to handle this case e.g. dynamic behaviour based on an optional second parameter, overloading, etc…