News for hackers. Stuff that matters.
Re:Functional Programming – How and Why by jemmyw on Monday January 02, 2023 @12:26AM (#34214671)
The example given isn't really functional programming is it? Or am I missing something? In those examples you start with an object, call a method on the object returning a new object, then call a method on that and so on. I like this kind of chaining in OOP.

Languages like JavaScript and Rust (and Go?) have blurred the lines between purely functional and purely imperative. I think I prefer that compromise position myself.

Re:Functional Programming – How and Why by brundolf on Monday January 02, 2023 @12:37AM (#34214739)
Method vs non-method calling syntax is a red herring; a method is just a function where you put the first argument on the left instead of inside the parenthesis

Hanging functions off of objects/types isn't really anti-functional either, as long as they don't mutate it

Functional programming is mainly about not changing state; you can do that with or without methods

Re:Functional Programming – How and Why by jemmyw on Monday January 02, 2023 @12:46AM (#34214787)
Well there's a certain anti functional feel to it because your functions are tied to the object rather than being able to process any given object or objects of different types.

Difference between functional style and functional language?

Re:Functional Programming – How and Why by valenterry on Monday January 02, 2023 @01:17AM (#34214937)
No, those things are totally orthogonal and people just mix it up because OOP came with mutations.

Bundling data and functions has pros and cons but has nothing to do with functional programming it.

Also, there isn't really a good definition for either functional style or functional language. If anything, there is a good definition for pure functional programming, but that's another beast alltogether and still is orthogonal to bundling data and functions.

Re:Functional Programming – How and Why by brundolf on Monday January 02, 2023 @12:56AM (#34214842)
> rather than being able to process any given object or objects of different types

Not necessarily- the functions can still be polymorphic. Rust does a particularly cool thing here, where any struct or trait method can be called in non-method syntax (or even passed as a first-class function!). I believe Julia also has type-based polymorphism while still being considered a functional-adjacent programming language. And then there are other languages where any function in scope can be called in method syntax, without being explicitly associated with the value's type (there's a name for this feature but I can't remember it)

> Difference between functional style and functional language?

I don't know the precise definitions well enough to distinguish them (though I'm not sure they have precise definitions)

Re:Functional Programming – How and Why by jemmyw on Monday January 02, 2023 @01:25AM (#34214978)
I'm familiar with rust but not with Julia. One pitfall I can see with calling this method chaining style functional is that you might not be aware of when a mutation occurred. For example, I've made the mistake before of calling .sort() I'm js on an array chain and it mutates in place, which you don't really expect given the other methods. At least rust makes this explicit.
Re:Functional Programming – How and Why by brundolf on Monday January 02, 2023 @01:33AM (#34215027)
> you might not be aware of when a mutation occurred

Yeah, this is a risk with any language that mixes some functional features/style in with non-functional features. Rust does a pretty good job of letting you mostly delineate the two, though there are still escape-hatches

I've actually been toying with a language design that has both, but draws a hard distinction between them. We'll see how it works out :)

But most of the time, if you're not using a totally pure functional language, functional programming is more a practice/style/ethos/feature-set than a hard constraint

Re:Functional Programming – How and Why by Hasnep on Monday January 02, 2023 @02:47AM (#34215411)
Julia has the convention that mutating functions have names that end with a bang, e.g.

  sort(x)
returns the sorted object, but

  sort!(x)
returns a "nothing" and mutates the object in place.
Re:Functional Programming – How and Why by TchoBeer on Monday January 02, 2023 @08:25AM (#34217569)
iirc this is notation that they adopted from rust.
Re:Functional Programming – How and Why by Jtsummers on Monday January 02, 2023 @11:09AM (#34219485)
More likely Scheme. Scheme used the ! signifier to indicate that something was being mutated. For instance `vector-copy` returns a fresh copy, `vector-copy!` copies into another vector, changing it.
Re:Functional Programming – How and Why by TchoBeer on Monday January 02, 2023 @11:17AM (#34219589)
Whether Julia took it from Rust or Scheme, or Rust took it from Scheme or Scheme took it from somewhere else, my point was that Julia did not invent this notation (this kinda sounds like an insult but it's actually not at all), and it's just a notation common a lot of functional-ish languages that allow mutation.
Re:Functional Programming – How and Why by Jtsummers on Monday January 02, 2023 @12:06PM (#34220336)
We are in agreement that Julia is not the origin of ! for this, I was just pointing out that if you want a historical take (what influenced what), Julia most likely got it from Scheme (whether it originated in Scheme or not is immaterial). Rust doesn't use ! to signify "This is a mutating function", it uses it to signify "This is a macro". Whereas Julia and Scheme use it as an indicator for the same thing: functions that modify their arguments. And Julia is known to have been influenced by Scheme, which existed when Julia's development started while Rust (publicly) did not.
Re:Functional Programming – How and Why by kaba0 on Tuesday January 03, 2023 @10:16AM (#34232382)
I’m fairly sure Ruby predates both of these languages by a lot and it does use the ! notation for similar things.
Re:Functional Programming – How and Why by brundolf on Monday January 02, 2023 @12:54PM (#34221130)
In rust ! signifies invoking a macro, so it couldn't be used like this in a function name even if you wanted to. Also, Rust allows you to notate immutable/mutating/owning for each individual argument type, so there wouldn't be much point:

  fn do_thing(a_owned: Foo, b_mutating: &mut Foo, c_immutable: &Foo) {
There is a convention to separate the two kinds of functions (consume and return in some, mutate in others), but that's the only commonality
Re:Functional Programming – How and Why by sideeffffect on Monday January 02, 2023 @08:21AM (#34217547)
> though I'm not sure they have precise definitions

Of course they don't. These "paradigms" like OOP or FP are just human made up terms _without any basis in theory_. Sometimes they can be practically useful when communicating with other humans, like we do now. But more and more people are starting to realize how meaningless/nonsensical these categorizations are (and always have been): FP vs OOP, compiled vs interpreted, static vs dynamic, etc. We might as well categorize languages based on the colour of their mascot.

See this for more https://old.reddit.com/r/ProgrammingLanguages/duplicates/6xt...

The closest thing to the definition of an FP language that I was able to come up with is "based on the Lambda calculus". Haskell is, Scheme is, F# is. But e.g. Scala isn't, it's fundamental building block isn't functions but objects. But many people do consider Scala to be an FP language.

So let's all be aware of the limitations of these (pseudo-)concepts.

Re:Functional Programming – How and Why by valenterry on Monday January 02, 2023 @09:09PM (#34226659)
That's not really true. Yeah, the term "FP" has been watered down but there was a proper definition: "FP is whene every expression of a program is referential transparent" and that's it. (https://en.wikipedia.org/wiki/Referential_transparency)

In other words, this is not even a property of a programming language. It is a property of the code itself. It's just that some languages make it easy or impossible to build a program in that style - or they even enforce it. Haskell however has escape hatches. And Scala is considered an FP language because, unlike Javascript/Lisp/Clojure/ML/Rust/... it really allows and supports(!) to make the whole program referential transparent.

Re:Functional Programming – How and Why by kazinator on Monday January 02, 2023 @11:38PM (#34227738)
* * *
Re:Functional Programming – How and Why by valenterry on Tuesday January 03, 2023 @12:26AM (#34228035)
Well, that depends a bit what you mean by "function-defining expression".

Let's say `(new function(input) { return input })` is a valid expression. If it then doesn't matter (in any circumstance) whether you do

    let myFunction = (new function(input) { return input })
    myFunction(1)
    myFunction(2)
or

    (new function(input) { return input })(1)
    (new function(input) { return input })(2)
that's when you can call the function-defining expression to be referentially transparent. If, on the contrary, creating a function increases a counter and you use that counter in your programing for something and it makes your program behave differently depending on how many functions are created, then the function creating expression would cease to be referential transparent.

I think that's not a bad example actually, because I assume it feels more natural to people to be able to treat an expression that creates a function in the way above and expecting that it won't change how the program behaves. And this is really what functional programming is about - it is exactly this feeling and guarantee that FP enforces throughout the whole application, not just in some places.

If you are talking about creating a named function (i.e. a class member) that is not an expression, then there isn't really much point in talking about it since we are now talking about definitions, not expressions anymore. Unless you can change/create definitions programmatically - in that case the code that does it programmatically is the one that needs to be considered, not the definition itself.

Re:Functional Programming – How and Why by kazinator on Tuesday January 03, 2023 @12:53AM (#34228219)
What is the value of

  let myFunction = ...
which can replace that whole construct so that the program remains the same? Or is this not functional?
Re:Functional Programming – How and Why by valenterry on Tuesday January 03, 2023 @01:35AM (#34228493)
I think you are confused. FP doesn't require any kind of token/syntax to be "replacable". It requires expressions to be "replacable" (RT).

A language could certainly treat assignments as expressions (some do) and have them return something, such as the value that is assigned to the variable or always null/unit. But we are now talking about a totally different thing.

Re:Functional Programming – How and Why by valenterry on Tuesday January 03, 2023 @01:38AM (#34228507)
To give a concrete example: Haskell supports something called do-notation. You cannot "replace" parts of it, because it is syntactic sugar that will turn into a number of expressions. But all of those expressions are then RT. In the same way you can have a C++ program that is FP (completely RT) but uses templates, which are obviously not "replacable". I hope that makes it more clear.
Re:Functional Programming – How and Why by kazinator on Tuesday January 03, 2023 @02:18AM (#34228763)
I'm just trying to follow the proposed definition of FP.

Turns out there are non-expressions present; yet somehow if just the expressions are referentially transparent, we have FP?

We have to say something about the kinds of non-expression thingys that are required/allowed and what their properties must be.

Assignments can be expressions, but they are not referentially transparent. If an assignment is replaced by its value, it's no longer performing the assignment. Hence, assignments are easily found to be incompatible with FP under the RT definition, which underscores that it is useful.

Re:Functional Programming – How and Why by valenterry on Wednesday January 04, 2023 @12:48AM (#34242451)
> Turns out there are non-expressions present; yet somehow if just the expressions are referentially transparent, we have FP?

Why "just"?

> We have to say something about the kinds of non-expression thingys that are required/allowed and what their properties must be.

Well, if there are syntactical constructs that will execute code at runtime, then we can essentially consider them expressions, even though sometimes they are restricted in how they can be used. For example, in Javascript and Java there is an if-syntax (call it if-statement or whatever) that will execute code but it doesn't return anything and you can "assign" the result to a variable. Obviously this breaks referential transparency (or can't do anything meaningful). We can still see it as an expression for the purpose of the definiton.

Other than that, as I said in my parallel post, if you have something like templates (which are not executing code at runtime), then they can do whatever you want, the only thing that matters is what expressions they will produce and if those are RT or not to fullfill the definition of FP.

> If an assignment is replaced by its value, it's no longer performing the assignment

And the funny thing is, it doesn't matter. Your code might stop compiling because you refer to a variable that isn't declared, yeah. And that's about it. But otherwise in a fully RT program it won't change the bebaviour of the program. EXCEPT if it is a reassignment. Which is why reassignments are violating RT and are therefore not a thing in FP - there can be specific exceptions (i.e. shadowing something in a different scope) but those aren't really reassignments, they just sometimes use the same syntax.

Re:Functional Programming – How and Why by kaba0 on Tuesday January 03, 2023 @10:12AM (#34232329)
Java is referentially transparent. It just really doesn’t mean what you believe it does. It means that one can replace a reference to a thing with the thing itself.

It is a syntax level term, muddying execution model is just not correct usage, see https://stackoverflow.com/questions/210835/what-is-referenti...

What you are looking for is simply and plainly “pureness”.

Re:Functional Programming – How and Why by valenterry on Tuesday January 10, 2023 @04:02AM (#34322199)
> Java is referentially transparent

Referential transparency is not a property of programming languages but expressions (or more general, parts of computer programs).

> It means that one can replace a reference to a thing with the thing itself.

That's not the common definition at all. Read the link I posted. In any case, I'm talking about evaluatable expressions, you talk about "references" - however you define that.

Even in your own stackoverflow link, the accepted answer says this:

> the thing that an expression refers to

Re:Functional Programming – How and Why by kaba0 on Tuesday January 10, 2023 @06:56AM (#34323452)
But expressions don’t mean the thing they evaluate to, this is an ad hoc meaning used in FP circles only. Is `fibonacci 1000` the integer value it evaluates to? No, it is an expression denoting the calculation of that value.

What’s missing from side-effect freedom or pureness? That is the property that allows replacing an expression with its value.

Re:Functional Programming – How and Why by valenterry on Tuesday January 10, 2023 @07:49AM (#34324040)
> But expressions don’t mean the thing they evaluate to, this is an ad hoc meaning used in FP circles only. Is `fibonacci 1000` the integer value it evaluates to? No, it is an expression denoting the calculation of that value.

Not sure what you are talking about now.

> What’s missing from side-effect freedom or pureness? That is the property that allows replacing an expression with its value.

I think you are just unfamiliar with the terminology, that's all.

See Wikpedia again:

> If a pure function is called with arguments that cause no side-effects, the result is constant with respect to that argument list (sometimes called referential transparency or idempotence), i.e., calling the pure function again with the same arguments returns the same result. (This can enable caching optimizations such as memoization.)

(https://en.wikipedia.org/wiki/Functional_programming#Pure_fu...)

There you go. All 3 terms in once sentence. Maybe, again, you disagree with Wikipedia and the definition and that's your good right, but I don't see any point in prolonging the discussion over that.

Re:Functional Programming – How and Why by sideeffffect on Monday January 02, 2023 @08:05AM (#34217447)
There's nothing anti-functional in bundling related functions into an object.

On the contrary, this helps with modularity, which is a good thing. You can then swap out the object for another object with the same interface, but where the functions (methods) have different implementations.

Re:Functional Programming – How and Why by galaxyLogic on Tuesday January 03, 2023 @03:42PM (#34237712)
An often overlooked feature of OOP is the use of pseudo-variable 'this' (or 'self in Smalltalk).

That is about name-scope. You can refer to your own method simply by its name via 'this', and when you call it you know it can access the state inside that particular object.

Without 'this' an object in JavaScript and other OOP languages could not access its own properties including it (possibly mutable) state.

Is there an equivalent to 'this' in purely FP languages?

Re:Functional Programming – How and Why by jemmyw on Monday January 02, 2023 @12:42AM (#34214764)
Man, the downvotes lol. If you disagree just write a reply, happy to be corrected or read others opinion
Re:Functional Programming – How and Why by Throwaway234590 on Monday January 02, 2023 @01:03AM (#34214872)
Exactly. It's why this forum is toxic, if you disagree with the techbro herd, you get downvoted.
Re:Functional Programming – How and Why by jemmyw on Monday January 02, 2023 @01:18AM (#34214938)
I didn't even disagree with anything, just asked a question! I'm not anti functional or anti imperative, they're both fine.

My point was I don't think it's functional to chain method calls in JavaScript. Maybe it is, although I think you'd very easily run into an unintentional issue, i.e. call .sort() on the array which mutates it.

Re:Functional Programming – How and Why by Throwaway234590 on Monday January 02, 2023 @02:54AM (#34215454)
It's a hairpulling experience trying to write functionally in javascript. All those imperative apis like sort as you mention. I will sometimes copy as in [...xs] but I always feel like I am swimming against the current. Plenty more to say but it appears this node has been flagged, it appears HN censors criticism. Saddening.
Re:Functional Programming – How and Why by freedomben on Monday January 02, 2023 @12:58PM (#34221174)
Being dead doesn't censor anything. After all, I'm here reading and replying 10 hours later. It just makes it invisible to people without "Show dead" enabled.

Your post most assuredly got down voted to death for calling "HN" "toxic." That's not constructive at all, and it inflames emotions which is the opposite of HN's goals of technical discussion.

I've taken many positions against the HN herd and yes many people do downvote on disagreement (which I agree they shouldn't), but given a bit of time it will typically even out. The new vouch system helps this even more.

Re:Functional Programming – How and Why by vram22 on Saturday January 07, 2023 @07:01PM (#34294460)
>Being dead doesn't censor anything. After all, I'm here reading and replying 10 hours later. It just makes it invisible to people without "Show dead" enabled.

IMO, effectively, it does censor it; not de jure, but de facto. (Hope I used those terms right, IANAL.)

Because my guess is that not many HN users know about the "showdead" setting. After all, not everyone is into tinkering with systems, tweaking settings, etc., even among developers, who I guess form a sizeable percentage of users here. Some of them just want to use the software as needed and get on with their lives, even though they may be technical.

Re:Functional Programming – How and Why by dang on Monday January 02, 2023 @04:59PM (#34224258)
Please don't do this here. It only makes things worse.

https://news.ycombinator.com/newsguidelines.html

Re:Functional Programming – How and Why by theteapot on Monday January 02, 2023 @02:27AM (#34215307)
> Languages like JavaScript and Rust (and Go?) have blurred the lines between purely functional and purely imperative. I think I prefer that compromise position myself.

What? The line blurring ones are the ones taking the comprising position right? So you're saying you prefer Javascript, Rust and Go?

Re:Functional Programming – How and Why by jemmyw on Monday January 02, 2023 @05:25AM (#34216360)
Yes I personally find those languages to be the sweet spot between very object structured like Java and C# (although I haven't used either for 15 years so I can't speak to how they're currently used) and FP languages. Javascript a little less so, it's just very flexible and Typescript adds the typing layer. Rust especially seems to take just enough of the FP style to get some nice benefits while also being a traditional imperative language. Just my personal opinion of course, I'm not an advocate for any particular style.
Re:Functional Programming – How and Why by kaba0 on Tuesday January 03, 2023 @10:18AM (#34232413)
Both C# and Java have incorporated many things from the FP paradigm.
Re:Functional Programming – How and Why by eyelidlessness on Monday January 02, 2023 @02:45AM (#34215403)
If a “method” returns a value, is it really a method? Does it mutate “this”? What does it mean to be an object, if you’re not being changed at all?
Re:Functional Programming – How and Why by Jtsummers on Monday January 02, 2023 @03:14AM (#34215577)
Yes, it is a method. It would be a “query” if it causes no changes but returns a value.
Re:Functional Programming – How and Why by Jtsummers on Monday January 02, 2023 @11:36AM (#34219879)
I wrote that other comment just before dozing off for the night because I was surprised no one else had replied yet. But to expand on it:

In Eiffel (which is an object oriented language), methods on objects are separated into twokind: commands and queries. This is also known as the "Command-Query Separation" principle. The idea is that commands are the ones causing changes to the systems and queries only inform you about the system. `a_set.add(item)` changes the set, while `a_set.has(item)` tells you about the set but makes no changes to it. It's very useful, and very common. I mean, I'd hope that `some_collection.Size()` doesn't actually change its size, that's not what it exists to do.

https://en.wikipedia.org/wiki/Command–query_separation

Re:Functional Programming – How and Why by kaba0 on Tuesday January 03, 2023 @10:20AM (#34232461)
Thanks, I wasn’t familiar with the name of this principle!

Though I feel these definitions of OOP are closing on the Actor model, so exact definitions are not really possible to give here.

Re:Functional Programming – How and Why by shadowgovt on Tuesday January 03, 2023 @03:41PM (#34237703)
Sometimes, depending on the nature of the implementation, Size() might do the work to compute the size, cache the result, and clear a dirty flag on the cache.

Not sure if that matters.

Re:Functional Programming – How and Why by galaxyLogic on Tuesday January 03, 2023 @08:59PM (#34240964)
It does not need to mutate this but it can:

1. Read the fields of 'this' 2. Write the fields of 'this' 3. Call other methods of 'this' (including "private" methods in many OOP languages)

That is very characteristic of OOP languages. Does anybody know if FP languages have something like the 'this' and if not what do they use instead?

Re:Functional Programming – How and Why by ookdatnog on Monday January 02, 2023 @02:52AM (#34215445)
Functional and object-oriented aren't two ends of a spectrum, they're orthogonal. Code can be both.

To program in a functional style means no more or less than to construct your program by composing referentially transparent functions (that is, functions that have no side effects, and whose output is deterministic based on the inputs -- in other words: the mathematical notion of a function). The solutions that are marked as functional in the post fulfill this criterium, so it's correct to call them functional solutions.

Whether your functions are written in method notation or not is not relevant to determining whether the program is written in a functional style.

Re:Functional Programming – How and Why by jstimpfle on Monday January 02, 2023 @04:06AM (#34215904)
OOP is not method notation. There's more to it (and arguably the notation part isn't required), and indeed you can't have both that and FP. OOP is the opposite of "referentially transparent".
Re:Functional Programming – How and Why by sideeffffect on Monday January 02, 2023 @08:01AM (#34217423)
Then it really depends what exactly you mean by OOP. Some people use the OOP features for modularity and structuring of the codebase, without any side effects/unmanaged mutation. Often they don't call it "OOP" then, but rather "a module system". But there isn't any theoretical distinction.

For example, I do _both_ Pure Functional Programming _and_ OOP (in the "module system" way) in Scala daily. And it works very nice IMHO, I encourage everybody to give it a try.

Use traits as interfaces for logical pieces of your business logic. Implement them in (case) classes which receive interfaces to other pieces of logic in their class constructor. Use a so called "Functional Effect System" like Cats Effect or ZIO to avoid raw side effects. And that's it, enjoy and profit.

Re:Functional Programming – How and Why by jstimpfle on Monday January 02, 2023 @08:10AM (#34217484)
It's impossible to get people to agree on what OOP is exactly, but almost everyone agrees that hiding/isolating mutable state (inside objects) is an essential part of it. Just google "what are objects in programming".
Re:Functional Programming – How and Why by sideeffffect on Monday January 02, 2023 @08:32AM (#34217626)
Totally agree that these paradigms are badly defined. See my other comment where I explain it more https://news.ycombinator.com/item?id=34217547

My point here was that all "OOP" languages (that I know) allow you, with all their "OOP feautres", to work with objects which actually don't contain any mutable state.

I'll let you be the judge whether it is still "OOP", but I know from experience that it's very practical for Software Engineering.

Re:Functional Programming – How and Why by kaba0 on Tuesday January 03, 2023 @09:58AM (#34232157)
This is a pet peeve of mine, but referential transparency really doesn’t mean what FP people use it for. They use it as a fancy name for the same thing as pureness. Referential transparency is a syntactic thing and most languages without macros are referentially transparent — see this answer: https://stackoverflow.com/questions/210835/what-is-referenti...
Re:Functional Programming – How and Why by ookdatnog on Thursday January 05, 2023 @11:49AM (#34262626)
When I talk about referential transparency in the context of FP, it's honestly of no consequence to me what the history of the term in philosophy is (mind you, I still find it interesting -- I didn't know this and it was nice learning about it -- but it doesn't significantly change my understanding of the term in the context of FP).

Technical terms can be overloaded, I don't think this is either surprising or problematic. Astrophysicists classify carbon as a metal; they're not wrong, it's just a peculiarity of the field that's almost always clear from context.

In the context of FP, the term "referential transparency" means that variables can be replaced with their definitions, and vice versa, without changing the semantics of the program. The term coincides with pureness, but IMO it emphasizes something different. "Pureness" is a negative definition, it the property of there not being any side effects. "Referential transparency" to me indicates what you can do with that purity: it allows you to reason algebraically about your program.

> most languages without macros are referentially transparent

I don't think so. In most languages, you cannot syntactically replace a variable with its definition and expect the semantics of your program to remain unchanged. For instance, in Python, given the following shared prefix:

    state = 0
    def f():
        nonlocal state
        state += 1
        return state
    
    x = f()
The programs

    x + x
and

    f() + f()
do not yield the same result, which is what you'd expect if referential transparency holds.
Re:Functional Programming – How and Why by vram22 on Monday January 02, 2023 @03:04AM (#34215507)
>In those examples you start with an object, call a method on the object returning a new object, then call a method on that and so on. I like this kind of chaining in OOP.

Then this post from my blog might be of interest:

Examples of method chaining in Python:

https://jugad2.blogspot.com/2016/02/examples-of-method-chain...

Re:Functional Programming – How and Why by jemmyw on Monday January 02, 2023 @07:12AM (#34217095)
Not really, I already know what it is and use it all the time. I mean, I just wrote about it. Plus I don't program in python.

Honestly, I just opened your page and it's not a great example. Consider the method chaining in the linked article that operates on an array, it's much closer to real problems imo, and more succinct.

Re:Functional Programming – How and Why by vram22 on Saturday January 07, 2023 @07:08PM (#34294523)
Which linked article?