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" <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 <jesse...@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 Jesse Claven <jesse...@gmail.com> wrote: >> >> Hey everyone! >> >> I propose adding `Function.const/2` as a function which for argument `x`, >> would always return `x`. >> >> ``` >> @spec const(any(), any()) :: any() >> def const(_original_value, new_value), do: new_value >> ``` >> >> This is somewhat similar to the new `Function.identity/1` in that it may >> seem like we've easily lived without it, but it does afford some more >> concise/semantic ways to represent a common pattern. >> >> ``` >> fn _ -> something_else() end >> ``` >> >> This would become: >> >> ``` >> const(something_else()) >> ``` >> >> ``` >> Enum.map([0,1,2,3], &Function.const/2) >> ``` >> >> I'm new to Elixir, so I'm not sure of the weight that the name `const` >> would carry, so there could be a more acceptable name. >> >> If accepted, I'd be happy to create a PR! >> >> Equivalents in other languages: >> >> - Haskell: >> https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Function.html#v:const >> - PureScript: >> https://pursuit.purescript.org/packages/purescript-const/4.1.0/docs/Data.Const >> - Elm: >> https://package.elm-lang.org/packages/elm/core/latest/Basics#always >> - Scala: >> https://www.scala-lang.org/api/current/scala/Function$.html#const[T,U](x:T)(y:U):T >> >> - Idris: >> https://www.idris-lang.org/docs/current/prelude_doc/docs/Prelude.Basics.html#Prelude.Basics.const >> >> >> >> Thanks for your time. >> >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to elixir-l...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/576949a3-93e2-4117-b1f1-ab4621f10e88%40googlegroups.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/576949a3-93e2-4117-b1f1-ab4621f10e88%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to elixir-l...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/f8b6009d-e21a-434a-96e0-e2c6ae3c1a0e%40googlegroups.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/f8b6009d-e21a-434a-96e0-e2c6ae3c1a0e%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to elixir-l...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/294d4f77-6b91-4316-a152-0c209fad12db%40googlegroups.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/294d4f77-6b91-4316-a152-0c209fad12db%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> >> >> >> -- >> >> >> >> Regards, >> >> Bruce Tate >> >> CEO >> >> >> >> [image: Image removed by sender.] >> >> >> >> Groxio, LLC. >> >> 512.799.9366 >> >> br...@grox.io >> >> grox.io >> >> -- >> You received this message because you are subscribed to the Google Groups >> "elixir-lang-core" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to elixir-l...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/elixir-lang-core/CAFXvW-6%3DfheYjjyQ7xiWYkP0B0t%2BfoGae9OGtkDDSvSpD4s_Sg%40mail.gmail.com >> >> <https://groups.google.com/d/msgid/elixir-lang-core/CAFXvW-6%3DfheYjjyQ7xiWYkP0B0t%2BfoGae9OGtkDDSvSpD4s_Sg%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> >> -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/1a49eabe-6509-41c7-b425-21e207737472%40googlegroups.com.