![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 22/04/2012 05:33 AM, Shay wrote:
> On Sat, 21 Apr 2012 16:18:46 -0500, Orchid Win7 v1 <voi### [at] dev null> wrote:
>
>>
>> 1. You can take a 5-argument function, pass it 2 argument, and get a
>> 3-argument function as the result.
>>
>> Examples:
>>
>> - (+1) takes a number and adds one to it.
>>
>> - (5 ==) takes a number and returns True if it's 5.
>>
>> - "map" takes a function and a list. "map abs" takes a list of numbers
>> and returns a list of positive numbers.
>
> I think I understand monads—I'll likely never try Haskell to find out
> for sure.
> I'm pretty sure I understand currying—at least as far as it goes in Python.
>
> But I don't understand how any of these are taking a 5 argument
> function, passing it 2 arguments, and getting a 3 argument function as a
> result.
I couldn't find an example of a 5-argument function to demonstrate with.
Generally, if you find yourself writing a function with that many
arguments, you're doing it wrong.
So instead, I demonstrated with a couple of 2-argument functions
generating 1-argument functions.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 22/04/2012 11:40 AM, Warp wrote:
> But that's the thing: It sounds so trivial as to defy sense. Why give
> a particular name to such a trivial thing?
One could argue that "calling a function" is a pretty trivial idea. But
it's still useful to have a name for it.
> But then when one starts asking questions like "so it's like giving
> default values to function parameters?" or "so it's like writing another
> function with less parameters that calls the first function by giving it
> some default values as the rest of the parameters?", the answer is something
> like "not really".
Providing default arguments is /kind of/ similar. The difference is that
usually you /can/ still provide explicit values which override the
defaults. With a curried function, you /cannot/ change the arguments
that have already been given. (Or even know if any arguments /have/ been
give yet. All you can see is what arguments remain.)
Writing a new function that takes one fewer arguments than an existing
one is like currying. Except that the idea behind "currying" is that
this is /automatic/. You don't have to code it yourself. It's
automatically available for all functions.
Finally, like I said, currying works backwards too: If a function call
happens to return a function as its result, you can just keep appending
arguments. "head function_list 7" and all that.
Curried functions mean that, at the language level, there is
fundamentally no difference between taking several arguments, and
functions that return functions that return functions.
As you say, it's /not/ an especially wild concept. But it's [usually]
not a feature that you can add without changing the language design.
That said, you could probably design some sort of object that has
methods for adding arguments, N at a time, and when it gets enough
arguments, it yields an answer. And that might reasonably be described
as currying.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 21/04/2012 10:53 PM, Le_Forgeron wrote:
> Le 21/04/2012 23:37, Orchid Win7 v1 nous fit lire :
>> "override operator;".
>
> For once, I'm glad C++ does not allow such!
Well, you'll notice that Haskell only does all this magical stuff IF YOU
EXPLICITLY REQUEST IT. So any block of monadic code either has a big
"do" right at the front of it, or all the ">>=" calls are written
explicitly. Either way, it's pretty obvious that "hey man, something
weird is going to happen here".
Haskell allows you to override many, many things: You can change what
number literals mean. You can change what string literals mean.
Obviously you can change what the various comparison and arithmetic
operators do. Monad in a sense allow you to override the semicolon
operator. You can even override pattern matching. But you know what? It
/doesn't/ let you override function call syntax.
> The overloading (?) of<< and>> is already enough trauma when dealing
> with streams... or not.
You know, considering that C++ demands an explicit type signature on
every tiny little thing... I'm having a hard time imagining how this
would ever be a problem. Especially given that the argument to << is
very, very likely to consist of at least one literal value.
> in fact, monade seems to be the<< with polymorphic type added.
There is a (<<) function in Haskell, in fact, and yes, it's to do with
monads. (It's the same as (>>), but with the arguments swapped around.)
> I wonder if there is a deep difference between haskell& forth... or a
> bit of lisp. Just that haskell dropped all ()...
Haskell dropped the brackets because
1. Functions are first-class, so a "named function" is merely an
ordinary variable who's "value" happens to be a function. So
distinguishing between foo and foo() is not needed.
2. Functions are curried, so foo(1, 2, 3) might run the function and
yield a result, or it might just yield a new, smaller function.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 22/04/2012 11:59 AM, Warp wrote:
> Orchid Win7 v1<voi### [at] dev null> wrote:
>> Further, let's pretend that you can create an anonymous function just by
>> writing
>
>> int function(int x) {return 2*x;}
>
> You can create anonymous functions. The syntax is:
>
> [](int x) { return 2*x; }
>
> (Of course that alone won't do anything because you can't call it, as
> it has no name. However, you can eg. create a variable that represents
> the function, like: "auto func = [](int x) { return 2*x; };". If you need
> to eg. return that function from another function, you'll have to use the
> std::function wrapper. Likewise if you need to give one as parameter to
> a non-templated or anonymous function.)
Mmm, interesting.
So how do you call such a function? Does it just override the usual
function call notation?
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> Heh, man... I thought "it inserts user-defined code between each pair of
>> statements" would a pretty simple idea. I guess not... ;-)
>
> I should have said that I am none the wiser. I still do not know what a
> monad is.
If you have a set of things which can be "added" and "subtracted" in a
certain technical sense, this is called a monoid.
(The technical rules say things like "if you add X and Y, and then
subtract Y, the result has to be X". Stuff like that.)
A monad is a little more complicated, but essentially, if you have
- A "box" type of some sort.
- A "return" function that takes a value and sticks it in a box.
- A "bind" function that takes a box and a function that returns a box,
and calls that function with the thing(s) in the input box.
then that's a monad.
(Once again, there's a bunch of technical rules that make this
mathematically rigorous. Technically the functions have to obey certain
rules - the "monad laws" - such as "bind x id == x". But usually any
sane way of implementing the two functions about will satisfy the
requirements.)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 22/04/2012 01:43 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] dev null> wrote:
>> 1. You can take a 5-argument function, pass it 2 argument, and get a
>> 3-argument function as the result.
>
> Would this be currying in C++?
>
> std::function<int(int)> multiplierFunction(int multiplier)
> {
> return [multiplier](int value) { return value * multiplier; };
> }
>
> The above function returns a function that takes an integral as parameter
> and returns it multiplied by the specified multiplier.
Yeah, I think that would satisfy my idea of "curried function".
The question is, does
multiplierFunction(3)(4)
or similar yield a 12?
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 22.04.2012 17:40, schrieb Orchid Win7 v1:
> On 22/04/2012 11:40 AM, Warp wrote:
>
>> But that's the thing: It sounds so trivial as to defy sense. Why give
>> a particular name to such a trivial thing?
>
> One could argue that "calling a function" is a pretty trivial idea. But
> it's still useful to have a name for it.
>
>> But then when one starts asking questions like "so it's like giving
>> default values to function parameters?" or "so it's like writing another
>> function with less parameters that calls the first function by giving it
>> some default values as the rest of the parameters?", the answer is
>> something
>> like "not really".
>
> Providing default arguments is /kind of/ similar. The difference is that
> usually you /can/ still provide explicit values which override the
> defaults. With a curried function, you /cannot/ change the arguments
> that have already been given. (Or even know if any arguments /have/ been
> give yet. All you can see is what arguments remain.)
>
> Writing a new function that takes one fewer arguments than an existing
> one is like currying. Except that the idea behind "currying" is that
> this is /automatic/. You don't have to code it yourself. It's
> automatically available for all functions.
Maybe that's what scrambles my mind whenever I read "Haskellists'"
explanations of stuff: They're so proud that Haskell does it
automatically for you, that they tend to deny the obvious parallels.
So yes: Currying *is* like writing a function that takes fewer
arguments, calling the original one and supplying (unchangeable)
defaults for the missing arguments.
And yes, apparently Haskell provides syntactic sugar for that. Wow. Big
deal.
> Finally, like I said, currying works backwards too: If a function call
> happens to return a function as its result, you can just keep appending
> arguments. "head function_list 7" and all that.
Again, nice-to-have syntactic sugar, but nothing conceptually
fascinating (as you noted yourself).
> That said, you could probably design some sort of object that has
> methods for adding arguments, N at a time, and when it gets enough
> arguments, it yields an answer. And that might reasonably be described
> as currying.
No. That might reasonably be described as nothing but bullshit.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 22.04.2012 17:56, schrieb Orchid Win7 v1:
> On 22/04/2012 01:43 PM, Warp wrote:
>> Orchid Win7 v1<voi### [at] dev null> wrote:
>>> 1. You can take a 5-argument function, pass it 2 argument, and get a
>>> 3-argument function as the result.
>>
>> Would this be currying in C++?
>>
>> std::function<int(int)> multiplierFunction(int multiplier)
>> {
>> return [multiplier](int value) { return value * multiplier; };
>> }
>>
>> The above function returns a function that takes an integral as parameter
>> and returns it multiplied by the specified multiplier.
>
> Yeah, I think that would satisfy my idea of "curried function".
>
> The question is, does
>
> multiplierFunction(3)(4)
>
> or similar yield a 12?
Sure, why not? multiplierFunction(3) returns a valid function, so
invoking its () operator calls the function with the respective
parameter(s).
(You could achieve the same syntax by having multiplierFunction() return
an object with an overridden () operator rather than a function, but of
course that would be cheating.)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka <ano### [at] anonymous org> wrote:
> So yes: Currying *is* like writing a function that takes fewer
> arguments, calling the original one and supplying (unchangeable)
> defaults for the missing arguments.
I think that the difference is that the new function is not static,
but it's generated dynamically. (In other words, what you end up is a
new function which fixes some of the parameters of the original function,
but the values to which they are fixed is determined at runtime rather
than at compile time.)
This means, if I understand correctly, that you could for example create
such functions in a loop (or, as we are talking about functional languages,
in a recursive manner), which is quite difficult to achieve with static,
compile-time functions. (I suppose you could try to emulate this in a
statically typed language with no lambda functions, but you would need
some kind of stack or something where the fixed parameter values are
stored.)
There are probably even deeper implications.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Orchid Win7 v1 <voi### [at] dev null> wrote:
> The question is, does
> multiplierFunction(3)(4)
> or similar yield a 12?
Yes.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |