Re: [elixir-core:9360] [Proposal] Add Function.const/2

2020-02-04 Thread Austin Ziegler
On Tue, Feb 4, 2020 at 10:04 AM Ben Wilson  wrote:

> > The code Function.constant(c) is much more expressive and descriptive
> than fn _ -> c end.
>
> To be clear, if this could work without macros, I'd be inclined to agree,
> although I recognize that there may be some who do not. My issue personally
> is that there simply isn't any function you can write that will behave this
> way, for all values of `c`. You could build `constant` as a macro, but I
> think that ends up killing the whole "name a concept" thing, because really
> the dominant concept at hand ends up being how macros work.
>

I don’t really have a strong opinion on this proposal, but I do think that
this could be done without macros and if naming a concept is important then
it’s worth considering. I do see one problem with `Function.constant/1` in
how it would be applied, because there would potentially need to be some
magic involved (which brings it back to possible macros).

The simplest implementation would be:

def constant(const), do: fn -> const end

That will work well for `Stream.repeatedly/1` as the function parameter is
`/0`, but not so well for `Enum.map/2` as the function parameter is `/1`.
This could be addressed with multiple functions (constant1/1, etc.) or with
an arity parameter (both examples shown below):

def constant(const), do: fn -> const end
def constant1(const), do: fn _ -> const end # OR
def constant(const, arity \\ 0)
def constant(const, 0), do: fn -> const end
def constant(const, 1), do: fn _ -> const end

I’m not sure it would be possible to know, at the call-site, whether you
needed a `/0` or `/1` anonymous function through macros, and I’m not sure
that it would be meaningful to have constant for _larger_ than `/{0,1}`
functions. But I do know that I have occasionally wanted to write:

Enum.map([0, 1, 2], &:padding) # or any other non-function value

and have it act as the correct type of function.

-a


> On Tuesday, February 4, 2020 at 9:39:48 AM UTC-5, Bruce Tate wrote:
>>
>> Thanks for the discussion, all. I enjoy being here.
>>
>> *Summary: I will bow out of this conversation after this one last
>> attempt. Feel free to skip it. *
>>
>> I will say that I would use this function frequently in my teaching and
>> in my day-to-day code if I had it. I think it describes a concept that is
>> well known in math, and useful in any functional language. For example,
>> resetting a counter in an agent or genserver with a similar API. Creating a
>> stream of constants as padding/initialization data of arbitrary length
>> (with take later).
>>
>> > we'll bloat the language.
>>
>> I don't think this is a good argument for foundational concepts. A
>> library that provides names for significant functions in math and
>> programming is important enough.
>>
>> > I’d argue back that this particular pattern, where you want a list of
>> fixed length with the same value, is much better served by
>> `List.duplicate/2`.
>>
>> Maybe. But List.duplicate/2 doesn't really solve the same problem.
>> Stream.repeatedly with Function.constant gives me  padding of an arbitrary
>> length, that I can then later instantiate based on the number of columns
>> that I need. It's a great pattern. It's basically fixed vs variable.
>>
>> > if I know anonymous functions, I know what’s going on.
>>
>> Variables, anonymous functions, and the like are not equivalent. A
>> library function has weight and descriptive ability that writing code just
>> doesn't. I can tell you that `fn(x) -> x end` and `Function.identity` are
>> not remotely equivalent when it comes to scanning code. There's a cost to
>> that much syntax.
>>
>> I'll say one more thing before moving on from this conversation.
>>
>> Naming concepts in code is important. The code Function.constant(c) is
>> much more expressive and descriptive than fn _ -> c end. It gives us a
>> common language across programming languages and theory plus math to
>> express ideas. We in the Elixir community often undersell the idea, and we
>> pay in the idioms that new coders must learn to be successful with our
>> language.
>>
>> *So thanks to all for a great discussion. I do recognize there's no
>> appetite for these ideas in Elixir, so I'll gracefully bow out. *
>>
>> -bt
>>
>>
>>
>> On Tue, Feb 4, 2020 at 8:58 AM Amos King  wrote:
>>
>>> Ben,
>>>
>>> That is how const is used in Haskell. Although without currying I don’t
>>> see how it is useful. I’m waiting to see an example that drives it home. I
>>> agree with Bruce about naming concepts but I don’t see the concept as
>>> useful in Elixir.
>>>
>>> Bruce, do you have a code sample using the idea?
>>>
>>> Amos King
>>> CEO
>>> Binary Noggin
>>>
>>> On Feb 4, 2020, at 07:35, Ben Wilson  wrote:
>>>
>>> 
>>> Addendum: I re-read the proposal because the const/1 vs const/2 thing
>>> confused me, and I'm seeing both in play there. The spec is arity 2, the
>>> example right after though is arity 1, and the Enum example is arity 2 but
>>> without a constant valu

Re: [elixir-core:9360] [Proposal] Add Function.const/2

2020-02-04 Thread Ben Wilson
> The code Function.constant(c) is much more expressive and descriptive 
than fn _ -> c end.

To be clear, if this could work without macros, I'd be inclined to agree, 
although I recognize that there may be some who do not. My issue personally 
is that there simply isn't any function you can write that will behave this 
way, for all values of `c`. You could build `constant` as a macro, but I 
think that ends up killing the whole "name a concept" thing, because really 
the dominant concept at hand ends up being how macros work.

On Tuesday, February 4, 2020 at 9:39:48 AM UTC-5, Bruce Tate wrote:
>
> Thanks for the discussion, all. I enjoy being here. 
>
> *Summary: I will bow out of this conversation after this one last attempt. 
> Feel free to skip it. *
>
> I will say that I would use this function frequently in my teaching and in 
> my day-to-day code if I had it. I think it describes a concept that is well 
> known in math, and useful in any functional language. For example, 
> resetting a counter in an agent or genserver with a similar API. Creating a 
> stream of constants as padding/initialization data of arbitrary length 
> (with take later). 
>
> > we'll bloat the language. 
>
> I don't think this is a good argument for foundational concepts. A library 
> that provides names for significant functions in math and programming is 
> important enough.
>
> > I’d argue back that this particular pattern, where you want a list of 
> fixed length with the same value, is much better served by 
> `List.duplicate/2`.
>
> Maybe. But List.duplicate/2 doesn't really solve the same problem. 
> Stream.repeatedly with Function.constant gives me  padding of an arbitrary 
> length, that I can then later instantiate based on the number of columns 
> that I need. It's a great pattern. It's basically fixed vs variable. 
>
> > if I know anonymous functions, I know what’s going on.
>
> Variables, anonymous functions, and the like are not equivalent. A library 
> function has weight and descriptive ability that writing code just doesn't. 
> I can tell you that `fn(x) -> x end` and `Function.identity` are not 
> remotely equivalent when it comes to scanning code. There's a cost to that 
> much syntax. 
>
> I'll say one more thing before moving on from this conversation. 
>
> Naming concepts in code is important. The code Function.constant(c) is 
> much more expressive and descriptive than fn _ -> c end. It gives us a 
> common language across programming languages and theory plus math to 
> express ideas. We in the Elixir community often undersell the idea, and we 
> pay in the idioms that new coders must learn to be successful with our 
> language.
>
> *So thanks to all for a great discussion. I do recognize there's no 
> appetite for these ideas in Elixir, so I'll gracefully bow out. *
>
> -bt
>
>
>
> On Tue, Feb 4, 2020 at 8:58 AM Amos King  > wrote:
>
>> Ben,
>>
>> That is how const is used in Haskell. Although without currying I don’t 
>> see how it is useful. I’m waiting to see an example that drives it home. I 
>> agree with Bruce about naming concepts but I don’t see the concept as 
>> useful in Elixir.
>>
>> Bruce, do you have a code sample using the idea?
>>
>> Amos King
>> CEO
>> Binary Noggin
>>
>> On Feb 4, 2020, at 07:35, Ben Wilson > 
>> wrote:
>>
>> 
>> Addendum: I re-read the proposal because the const/1 vs const/2 thing 
>> confused me, and I'm seeing both in play there. The spec is arity 2, the 
>> example right after though is arity 1, and the Enum example is arity 2 but 
>> without a constant value. The Enum example perhaps makes the most sense, 
>> because you could do:
>>
>> ```
>> Enum.map([1,2,3,4], &const(&1, :foo))
>> ```
>> which would return `[:foo, :foo, :foo, :foo]` effectively replacing the 
>> contents of the list with all `:foo`. Is that the idea?
>>
>> On Tuesday, February 4, 2020 at 8:16:53 AM UTC-5, Ben Wilson wrote:
>>>
>>> I agree with Michal. Additionally, I'm not clear how `const/1` could be 
>>> used in Bruce's example at all.
>>>
>>> To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent 
>>> when `const/1` is merely a function. This becomes readily apparent when 
>>> `foo()` is side effects or side causes. In the first case, `foo()` is never 
>>> evaluated until the wrapping function is called, in the case of `const/1` 
>>> however the function is evaluated and then its return value bound over by a 
>>> function. Eg: `fn -> DateTime.utc_now() end` will always return the current 
>>> time when evaluated, where as `const(DateTime.utc_now())` will evaluate the 
>>> current time once and then always return that same time.
>>>
>>> That might sound useful, except that we already can do that by simply 
>>> binding the return value of `DateTime.utc_now()` to a variable and passing 
>>> that variable around. I'm having difficulty coming up with a scenario 
>>> where, instead of simply having the value, I have the value wrapped in an 
>>> anonymous function that I need to

Re: [elixir-core:9358] [Proposal] Add Function.const/2

2020-02-04 Thread Bruce Tate
Thanks for the discussion, all. I enjoy being here.

*Summary: I will bow out of this conversation after this one last attempt.
Feel free to skip it. *

I will say that I would use this function frequently in my teaching and in
my day-to-day code if I had it. I think it describes a concept that is well
known in math, and useful in any functional language. For example,
resetting a counter in an agent or genserver with a similar API. Creating a
stream of constants as padding/initialization data of arbitrary length
(with take later).

> we'll bloat the language.

I don't think this is a good argument for foundational concepts. A library
that provides names for significant functions in math and programming is
important enough.

> I’d argue back that this particular pattern, where you want a list of
fixed length with the same value, is much better served by
`List.duplicate/2`.

Maybe. But List.duplicate/2 doesn't really solve the same problem.
Stream.repeatedly with Function.constant gives me  padding of an arbitrary
length, that I can then later instantiate based on the number of columns
that I need. It's a great pattern. It's basically fixed vs variable.

> if I know anonymous functions, I know what’s going on.

Variables, anonymous functions, and the like are not equivalent. A library
function has weight and descriptive ability that writing code just doesn't.
I can tell you that `fn(x) -> x end` and `Function.identity` are not
remotely equivalent when it comes to scanning code. There's a cost to that
much syntax.

I'll say one more thing before moving on from this conversation.

Naming concepts in code is important. The code Function.constant(c) is much
more expressive and descriptive than fn _ -> c end. It gives us a common
language across programming languages and theory plus math to express
ideas. We in the Elixir community often undersell the idea, and we pay in
the idioms that new coders must learn to be successful with our language.

*So thanks to all for a great discussion. I do recognize there's no
appetite for these ideas in Elixir, so I'll gracefully bow out. *

-bt



On Tue, Feb 4, 2020 at 8:58 AM Amos King  wrote:

> Ben,
>
> That is how const is used in Haskell. Although without currying I don’t
> see how it is useful. I’m waiting to see an example that drives it home. I
> agree with Bruce about naming concepts but I don’t see the concept as
> useful in Elixir.
>
> Bruce, do you have a code sample using the idea?
>
> Amos King
> CEO
> Binary Noggin
>
> On Feb 4, 2020, at 07:35, Ben Wilson  wrote:
>
> 
> Addendum: I re-read the proposal because the const/1 vs const/2 thing
> confused me, and I'm seeing both in play there. The spec is arity 2, the
> example right after though is arity 1, and the Enum example is arity 2 but
> without a constant value. The Enum example perhaps makes the most sense,
> because you could do:
>
> ```
> Enum.map([1,2,3,4], &const(&1, :foo))
> ```
> which would return `[:foo, :foo, :foo, :foo]` effectively replacing the
> contents of the list with all `:foo`. Is that the idea?
>
> On Tuesday, February 4, 2020 at 8:16:53 AM UTC-5, Ben Wilson wrote:
>>
>> I agree with Michal. Additionally, I'm not clear how `const/1` could be
>> used in Bruce's example at all.
>>
>> To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent
>> when `const/1` is merely a function. This becomes readily apparent when
>> `foo()` is side effects or side causes. In the first case, `foo()` is never
>> evaluated until the wrapping function is called, in the case of `const/1`
>> however the function is evaluated and then its return value bound over by a
>> function. Eg: `fn -> DateTime.utc_now() end` will always return the current
>> time when evaluated, where as `const(DateTime.utc_now())` will evaluate the
>> current time once and then always return that same time.
>>
>> That might sound useful, except that we already can do that by simply
>> binding the return value of `DateTime.utc_now()` to a variable and passing
>> that variable around. I'm having difficulty coming up with a scenario
>> where, instead of simply having the value, I have the value wrapped in an
>> anonymous function that I need to call.
>>
>> Consequently, I struggle to see where `const/1` can actually be used, or
>> how it would work. In the example in the initial proposal, there is this:
>>
>> ```
>> Enum.map([0,1,2,3], &Function.const/2)
>> ```
>>
>> As a minor note, presumably that should be `const/1`, right? More
>> importantly, what is the return value here? If it's `[0, 1, 2, 3]` then
>> `const/1` is equivalent to `identity`. If it's
>>
>> ```
>> [fn -> 1 end, fn -> 2 end, fn -> 3 end, fn -> 4 end]
>> ```
>>
>> then a simple list of integers seems universally more useful.
>>
>> On Tuesday, February 4, 2020 at 5:03:39 AM UTC-5, Michał Muskała wrote:
>>>
>>> I’d argue back that this particular pattern, where you want a list of
>>> fixed length with the same value, is much better served by
>>> `List.duplicate

Re: [elixir-core:9357] [Proposal] Add Function.const/2

2020-02-04 Thread Amos King
Ben,

That is how const is used in Haskell. Although without currying I don’t see how 
it is useful. I’m waiting to see an example that drives it home. I agree with 
Bruce about naming concepts but I don’t see the concept as useful in Elixir.

Bruce, do you have a code sample using the idea?

Amos King
CEO
Binary Noggin

> On Feb 4, 2020, at 07:35, Ben Wilson  wrote:
> 
> 
> Addendum: I re-read the proposal because the const/1 vs const/2 thing 
> confused me, and I'm seeing both in play there. The spec is arity 2, the 
> example right after though is arity 1, and the Enum example is arity 2 but 
> without a constant value. The Enum example perhaps makes the most sense, 
> because you could do:
> 
> ```
> Enum.map([1,2,3,4], &const(&1, :foo))
> ```
> which would return `[:foo, :foo, :foo, :foo]` effectively replacing the 
> contents of the list with all `:foo`. Is that the idea?
> 
>> On Tuesday, February 4, 2020 at 8:16:53 AM UTC-5, Ben Wilson wrote:
>> I agree with Michal. Additionally, I'm not clear how `const/1` could be used 
>> in Bruce's example at all.
>> 
>> To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent 
>> when `const/1` is merely a function. This becomes readily apparent when 
>> `foo()` is side effects or side causes. In the first case, `foo()` is never 
>> evaluated until the wrapping function is called, in the case of `const/1` 
>> however the function is evaluated and then its return value bound over by a 
>> function. Eg: `fn -> DateTime.utc_now() end` will always return the current 
>> time when evaluated, where as `const(DateTime.utc_now())` will evaluate the 
>> current time once and then always return that same time.
>> 
>> That might sound useful, except that we already can do that by simply 
>> binding the return value of `DateTime.utc_now()` to a variable and passing 
>> that variable around. I'm having difficulty coming up with a scenario where, 
>> instead of simply having the value, I have the value wrapped in an anonymous 
>> function that I need to call.
>> 
>> Consequently, I struggle to see where `const/1` can actually be used, or how 
>> it would work. In the example in the initial proposal, there is this:
>> 
>> ```
>> Enum.map([0,1,2,3], &Function.const/2)
>> ```
>> 
>> As a minor note, presumably that should be `const/1`, right? More 
>> importantly, what is the return value here? If it's `[0, 1, 2, 3]` then 
>> `const/1` is equivalent to `identity`. If it's
>> 
>> ```
>> [fn -> 1 end, fn -> 2 end, fn -> 3 end, fn -> 4 end]
>> ```
>> 
>> then a simple list of integers seems universally more useful.
>> 
>>> On Tuesday, February 4, 2020 at 5:03:39 AM UTC-5, Michał Muskała wrote:
>>> I’d argue back that this particular pattern, where you want a list of fixed 
>>> length with the same value, is much better served by `List.duplicate/2`.
>>> 
>>>  
>>> 
>>> I think in general, higher order combinator functions like identity, const, 
>>> flip, and friends are usually used to facilitate the point-free style of 
>>> programming in languages like Haskell. And in general point-free style 
>>> usually does not lead to the most readable code.
>>> 
>>>  
>>> 
>>> Again, referring to the example provided, if I know anonymous functions, I 
>>> know what’s going on. When using `Funcion.const`, I have to understand that 
>>> concept as well. There’s one extra thing to learn.
>>> 
>>>  
>>> 
>>> Michał.
>>> 
>>>  
>>> 
>>> From: "elixir-l...@googlegroups.com"  on 
>>> behalf of Bruce Tate 
>>> Reply to: "elixir-l...@googlegroups.com" 
>>> Date: Monday, 3 February 2020 at 11:47
>>> To: "elixir-l...@googlegroups.com" 
>>> Subject: Re: [elixir-core:9353] [Proposal] Add Function.const/2
>>> 
>>>  
>>> 
>>> My counterpoint is this. Any time you can name a concept that makes it 
>>> easier to see what's going on, it's important. 
>>> 
>>>  
>>> 
>>> Examples: 
>>> 
>>> * Create back padding of four blank table cells
>>> 
>>> * use with Stream.repeatedly and take, for example, to initialize a data 
>>> structure for OTP. 
>>> 
>>>  
>>> 
>>> I do these two things with pretty good frequency because I build responsive 
>>> layouts often needing tabular structure, but without HTML tables. 
>>> 
>>>  
>>> 
>>> Say you are laying out tables that are responsive but without HTML tables. 
>>> You
>>> 
>>> d want to add padding to the end of uneven rows. To create the padding 
>>> you'd do 
>>> 
>>>  
>>> 
>>> Stream.repeatedly( fn -> :padding end) |> Enum.take(4)  
>>>  
>>> 
>>> where :padding is the constant padding you want. This pattern comes up with 
>>> some regularity in my user interfaces. It doesn't hurt anything, and it 
>>> would be a great addition to the function module. 
>>> 
>>>  
>>> 
>>> I like this proposal. This is exactly the kind of function you'd expect to 
>>> see in the module. 
>>> 
>>>  
>>> 
>>> +1 from me. 
>>> 
>>>  
>>> 
>>> -bt
>>> 
>>>  
>>> 
>>> On Sun, Feb 2, 2020 at 2:42 PM Jesse Claven  wrote:
>>> 
>>> That all makes sense! I would say that in 

Re: [elixir-core:9357] [Proposal] Add Function.const/2

2020-02-04 Thread Ben Wilson
Addendum: I re-read the proposal because the const/1 vs const/2 thing 
confused me, and I'm seeing both in play there. The spec is arity 2, the 
example right after though is arity 1, and the Enum example is arity 2 but 
without a constant value. The Enum example perhaps makes the most sense, 
because you could do:

```
Enum.map([1,2,3,4], &const(&1, :foo))
```
which would return `[:foo, :foo, :foo, :foo]` effectively replacing the 
contents of the list with all `:foo`. Is that the idea?

On Tuesday, February 4, 2020 at 8:16:53 AM UTC-5, Ben Wilson wrote:
>
> I agree with Michal. Additionally, I'm not clear how `const/1` could be 
> used in Bruce's example at all.
>
> To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent 
> when `const/1` is merely a function. This becomes readily apparent when 
> `foo()` is side effects or side causes. In the first case, `foo()` is never 
> evaluated until the wrapping function is called, in the case of `const/1` 
> however the function is evaluated and then its return value bound over by a 
> function. Eg: `fn -> DateTime.utc_now() end` will always return the current 
> time when evaluated, where as `const(DateTime.utc_now())` will evaluate the 
> current time once and then always return that same time.
>
> That might sound useful, except that we already can do that by simply 
> binding the return value of `DateTime.utc_now()` to a variable and passing 
> that variable around. I'm having difficulty coming up with a scenario 
> where, instead of simply having the value, I have the value wrapped in an 
> anonymous function that I need to call.
>
> Consequently, I struggle to see where `const/1` can actually be used, or 
> how it would work. In the example in the initial proposal, there is this:
>
> ```
> Enum.map([0,1,2,3], &Function.const/2)
> ```
>
> As a minor note, presumably that should be `const/1`, right? More 
> importantly, what is the return value here? If it's `[0, 1, 2, 3]` then 
> `const/1` is equivalent to `identity`. If it's
>
> ```
> [fn -> 1 end, fn -> 2 end, fn -> 3 end, fn -> 4 end]
> ```
>
> then a simple list of integers seems universally more useful.
>
> On Tuesday, February 4, 2020 at 5:03:39 AM UTC-5, Michał Muskała wrote:
>>
>> I’d argue back that this particular pattern, where you want a list of 
>> fixed length with the same value, is much better served by 
>> `List.duplicate/2`.
>>
>>  
>>
>> I think in general, higher order combinator functions like identity, 
>> const, flip, and friends are usually used to facilitate the point-free 
>> style of programming in languages like Haskell. And in general point-free 
>> style usually does not lead to the most readable code. 
>>
>>  
>>
>> Again, referring to the example provided, if I know anonymous functions, 
>> I know what’s going on. When using `Funcion.const`, I have to understand 
>> that concept as well. There’s one extra thing to learn.
>>
>>  
>>
>> Michał.
>>
>>  
>>
>> *From: *"elixir-l...@googlegroups.com"  on 
>> behalf of Bruce Tate 
>> *Reply to: *"elixir-l...@googlegroups.com" 
>> *Date: *Monday, 3 February 2020 at 11:47
>> *To: *"elixir-l...@googlegroups.com" 
>> *Subject: *Re: [elixir-core:9353] [Proposal] Add Function.const/2
>>
>>  
>>
>> My counterpoint is this. Any time you can name a concept that makes it 
>> easier to see what's going on, it's important. 
>>
>>  
>>
>> Examples: 
>>
>> * Create back padding of four blank table cells
>>
>> * use with Stream.repeatedly and take, for example, to initialize a 
>> data structure for OTP. 
>>
>>  
>>
>> I do these two things with pretty good frequency because I build 
>> responsive layouts often needing tabular structure, but without HTML 
>> tables. 
>>
>>  
>>
>> Say you are laying out tables that are responsive but without HTML 
>> tables. You
>>
>> d want to add padding to the end of uneven rows. To create the padding 
>> you'd do 
>>
>>  
>>
>> Stream.repeatedly( fn -> :padding end) |> Enum.take(4)  
>>
>>  
>>
>> where :padding is the constant padding you want. This pattern comes up 
>> with some regularity in my user interfaces. It doesn't hurt anything, and 
>> it would be a great addition to the function module. 
>>
>>  
>>
>> I like this proposal. This is exactly the kind of function you'd expect 
>> to see in the module. 
>>
>>  
>>
>> +1 from me. 
>>
>>  
>>
>> -bt
>>
>>  
>>
>> On Sun, Feb 2, 2020 at 2:42 PM Jesse Claven  wrote:
>>
>> That all makes sense! I would say that in Elm it's used somewhat 
>> frequently. I don't have access to the previous code that I worked on 
>> (changed jobs), so unfortunately I'm unable to grep for `always` to find 
>> some good examples.
>>
>>  
>>
>> In the codebase at my new job, there's a couple of places where `fn _ -> 
>> something` is (my original example in this thread). It's basically for 
>> anywhere you'd want to ignore some value, and always return something else. 
>> I tried searching through GitHub for that code sample but the search 
>> functionality was a

Re: [elixir-core:9356] [Proposal] Add Function.const/2

2020-02-04 Thread Ben Wilson
I agree with Michal. Additionally, I'm not clear how `const/1` could be 
used in Bruce's example at all.

To elaborate,  `fn -> foo() end` and `const(foo())` cannot be equivalent 
when `const/1` is merely a function. This becomes readily apparent when 
`foo()` is side effects or side causes. In the first case, `foo()` is never 
evaluated until the wrapping function is called, in the case of `const/1` 
however the function is evaluated and then its return value bound over by a 
function. Eg: `fn -> DateTime.utc_now() end` will always return the current 
time when evaluated, where as `const(DateTime.utc_now())` will evaluate the 
current time once and then always return that same time.

That might sound useful, except that we already can do that by simply 
binding the return value of `DateTime.utc_now()` to a variable and passing 
that variable around. I'm having difficulty coming up with a scenario 
where, instead of simply having the value, I have the value wrapped in an 
anonymous function that I need to call.

Consequently, I struggle to see where `const/1` can actually be used, or 
how it would work. In the example in the initial proposal, there is this:

```
Enum.map([0,1,2,3], &Function.const/2)
```

As a minor note, presumably that should be `const/1`, right? More 
importantly, what is the return value here? If it's `[0, 1, 2, 3]` then 
`const/1` is equivalent to `identity`. If it's

```
[fn -> 1 end, fn -> 2 end, fn -> 3 end, fn -> 4 end]
```

then a simple list of integers seems universally more useful.

On Tuesday, February 4, 2020 at 5:03:39 AM UTC-5, Michał Muskała wrote:
>
> I’d argue back that this particular pattern, where you want a list of 
> fixed length with the same value, is much better served by 
> `List.duplicate/2`.
>
>  
>
> I think in general, higher order combinator functions like identity, 
> const, flip, and friends are usually used to facilitate the point-free 
> style of programming in languages like Haskell. And in general point-free 
> style usually does not lead to the most readable code. 
>
>  
>
> Again, referring to the example provided, if I know anonymous functions, I 
> know what’s going on. When using `Funcion.const`, I have to understand that 
> concept as well. There’s one extra thing to learn.
>
>  
>
> Michał.
>
>  
>
> *From: *"elixir-l...@googlegroups.com " <
> elixir-l...@googlegroups.com > on behalf of Bruce Tate <
> br...@grox.io >
> *Reply to: *"elixir-l...@googlegroups.com " <
> elixir-l...@googlegroups.com >
> *Date: *Monday, 3 February 2020 at 11:47
> *To: *"elixir-l...@googlegroups.com " <
> elixir-l...@googlegroups.com >
> *Subject: *Re: [elixir-core:9353] [Proposal] Add Function.const/2
>
>  
>
> My counterpoint is this. Any time you can name a concept that makes it 
> easier to see what's going on, it's important. 
>
>  
>
> Examples: 
>
> * Create back padding of four blank table cells
>
> * use with Stream.repeatedly and take, for example, to initialize a 
> data structure for OTP. 
>
>  
>
> I do these two things with pretty good frequency because I build 
> responsive layouts often needing tabular structure, but without HTML 
> tables. 
>
>  
>
> Say you are laying out tables that are responsive but without HTML tables. 
> You
>
> d want to add padding to the end of uneven rows. To create the padding 
> you'd do 
>
>  
>
> Stream.repeatedly( fn -> :padding end) |> Enum.take(4)  
>
>  
>
> where :padding is the constant padding you want. This pattern comes up 
> with some regularity in my user interfaces. It doesn't hurt anything, and 
> it would be a great addition to the function module. 
>
>  
>
> I like this proposal. This is exactly the kind of function you'd expect to 
> see in the module. 
>
>  
>
> +1 from me. 
>
>  
>
> -bt
>
>  
>
> On Sun, Feb 2, 2020 at 2:42 PM Jesse Claven  > wrote:
>
> That all makes sense! I would say that in Elm it's used somewhat 
> frequently. I don't have access to the previous code that I worked on 
> (changed jobs), so unfortunately I'm unable to grep for `always` to find 
> some good examples.
>
>  
>
> In the codebase at my new job, there's a couple of places where `fn _ -> 
> something` is (my original example in this thread). It's basically for 
> anywhere you'd want to ignore some value, and always return something else. 
> I tried searching through GitHub for that code sample but the search 
> functionality was a little subpar.
>
>  
>
> I understand about keeping the stdlib small, but for a relatively small 
> function, and one that's considered "table stakes" in most FP languages, 
> perhaps it would be a good fit?
>
>
> On Thursday, 30 January 2020 11:20:58 UTC, Wiebe-Marten Wijnja wrote: 
>
> The reason `Function.identity/1` was added after it was requested many 
> times previously, was that at some point everyone agreed that it would 
> improve Elixir's documentation, because it is easier to search for than 
> `&(&1)`.
>
> The `const` pattern is much less wide-spread. In e.g. Haskell it sees some 
>

Re: [elixir-core:9354] [Proposal] Add Function.const/2

2020-02-04 Thread Michał Muskała
I’d argue back that this particular pattern, where you want a list of fixed 
length with the same value, is much better served by `List.duplicate/2`.

I think in general, higher order combinator functions like identity, const, 
flip, and friends are usually used to facilitate the point-free style of 
programming in languages like Haskell. And in general point-free style usually 
does not lead to the most readable code.

Again, referring to the example provided, if I know anonymous functions, I know 
what’s going on. When using `Funcion.const`, I have to understand that concept 
as well. There’s one extra thing to learn.

Michał.

From: "elixir-lang-core@googlegroups.com"  
on behalf of Bruce Tate 
Reply to: "elixir-lang-core@googlegroups.com" 

Date: Monday, 3 February 2020 at 11:47
To: "elixir-lang-core@googlegroups.com" 
Subject: Re: [elixir-core:9353] [Proposal] Add Function.const/2

My counterpoint is this. Any time you can name a concept that makes it easier 
to see what's going on, it's important.

Examples:
* Create back padding of four blank table cells
* use with Stream.repeatedly and take, for example, to initialize a data 
structure for OTP.

I do these two things with pretty good frequency because I build responsive 
layouts often needing tabular structure, but without HTML tables.

Say you are laying out tables that are responsive but without HTML tables. You
d want to add padding to the end of uneven rows. To create the padding you'd do


Stream.repeatedly( fn -> :padding end) |> Enum.take(4)

where :padding is the constant padding you want. This pattern comes up with 
some regularity in my user interfaces. It doesn't hurt anything, and it would 
be a great addition to the function module.

I like this proposal. This is exactly the kind of function you'd expect to see 
in the module.

+1 from me.

-bt

On Sun, Feb 2, 2020 at 2:42 PM Jesse Claven 
mailto:jesse.cla...@gmail.com>> wrote:
That all makes sense! I would say that in Elm it's used somewhat frequently. I 
don't have access to the previous code that I worked on (changed jobs), so 
unfortunately I'm unable to grep for `always` to find some good examples.

In the codebase at my new job, there's a couple of places where `fn _ -> 
something` is (my original example in this thread). It's basically for anywhere 
you'd want to ignore some value, and always return something else. I tried 
searching through GitHub for that code sample but the search functionality was 
a little subpar.

I understand about keeping the stdlib small, but for a relatively small 
function, and one that's considered "table stakes" in most FP languages, 
perhaps it would be a good fit?

On Thursday, 30 January 2020 11:20:58 UTC, Wiebe-Marten Wijnja wrote:

The reason `Function.identity/1` was added after it was requested many times 
previously, was that at some point everyone agreed that it would improve 
Elixir's documentation, because it is easier to search for than `&(&1)`.

The `const` pattern is much less wide-spread. In e.g. Haskell it sees some use 
in places where it is the single (or at least by far the simplest) way to make 
things typecheck in a pure functional environment.

In Elixir, I suspect that it would be used much less commonly. The fact that 
our functions contain statements that are executed from top to bottom and 
rebindable variable names means that we are even less likely to use it anywhere.

As such, I don't think `const` is a function that is important enough to 
include in the standard library.



Of course, I'm very much open to evidence of the contrary ^_^. Do you have any 
example code of where you'd see `const` being useful?



~Marten/Qqwy
On 30-01-2020 10:24, Jesse Claven wrote:
Hey Amos,

Ah that's right. Every now and then I'm reminded that Elixir doesn't support 
currying when I try to do something haha Your suggestion makes sense.

Would there be any downsides to having it, even if it isn't the most incredible 
function? Again to call on the `Function.identity/1`, and it's discussion, it's 
useful when it's useful for concise and semantic code.

On Wednesday, 29 January 2020 22:43:51 UTC, Amos King - Binary Noggin wrote:
Jesse,

I see where you are going, but Elixir doesn't have currying. For instance, the 
last example you gave will return an error.

You could make it work by changing it a bit.

`@spec const(a) :: fn(any() -> a) when a: var`

So, const would return an fn instead of taking two arguments. I don't know how 
useful that would be in the long run. I know it is common in function 
programming, but I don't see it being extremely helpful in Elixir.

I'm ready to be convinced.

Cheers,

Amos King
CEO
Binary Noggin
http://binarynoggin.com #business
https://elixiroutlaws.com #elixir podcast
http://thisagilelife.com #podcast

===

I welcome VSRE emails. Learn more at http://vsre.info/

===


On Wed, Jan 29, 2020 at 4:01 PM Je