3 ms·
> The answer is that I would like to do without return statements if and as much as I can. We will see how much that is. In general, I am in favor of expression
by pwdisswordfish8 5y ago
> The answer is that I would like to do without return statements if and as much as I can. We will see how much that is. In general, I am in favor of expression-orientation in programming languages.
Rust is as expression-oriented as they get, and it does feature return statements (well, expressions: they have the empty type, implicitly convertible to any other type). I don’t see how those two are supposed to be exclusive. In fact, they very much go hand in hand: ‘expression-oriented’ is just another name for functional programming, and a return statement is just a limited (non-reified) form of continuations, a well-known concept under this paradigm. I don’t know what’s to write about here, really.
Also, it’s pretty ironic to see the article support its claims by a quote from Guy Steele disparaging functional programming, immediately followed by an example like
#Blinker{ #seconds: 1, #active: true} → ref:gpio:17.
which looks like mapping over a generator in all but name.
- mucholove 5y agoMaybe it has to do with coherence of objects as collections of functions and the fact that they contain state. I love objects and talking about them as living creatures. :) They’re sort of like functions that include a long set of parameters. The one thing I wouldn’t know how to do / name in functional pure functional programming is an incremental parser. My sense is that would probably have to pass an “object” like parameter like in C that gets updated by the function. What am I missing?
- Dzugaru 5y agoYou pass a state and return a new, modified state. You can, however, "pass" many other things in functional programming - see monads (also called computation expressions). I recommend fsharpforfunandprofit website for gentle introduction into FP (and a language called F# which is basically OCaml) and what it can do (especially in parsers area)
- ProfHewitt 5y agoThe monad pattern can much less efficient than concurrency by factors of hundreds.
- mpweiher 5y agoIt's fascinating that you see this as a functional construct. The call/return mindset is incredibly strong, and we map (sic) everything to it, no matter whether it's appropriate or not. What is actually there is a connection expression, connecting two objects. The first object is a data source, generating values at a fixed rate. The second object is a reference to the object identified by the polymorphic identifier "gpio:17". What is that? Pin 17 on the Raspberry Pi GPIO connector. But "gpio:17" is the current value. By taking the ref:, I can talk about the variable itself, which I can connect as a sink of a dataflow. In fact, I can connect any variable as the sink to a dataflow. So the following: #Blinker{ #seconds: 1, #active: true} → ref:file:/tmp/blinker.txt. would change the contents of the file in question every second. It would not append to the file, that would be accomplished by getting the stream: #Blinker{ #seconds: 1, #active: true} → ref:file:/tmp/blinker.txt asStream. Or you could just use stdout: #Blinker{ #seconds: 1, #active: true} → stdout. But coming back to ref:gpio:17, to me this seems about as effectful as possible, in my test setup that literally lights up an LED, so about as non-functional as you can get.
- magicalhippo 5y agoI was very confused by the GPIO example. Where does active get set to false, and after how long?
- ghusbands 5y agoIt doesn't, I think. Active is whether or not the blinker is active; though I'd have expected a default for that. The blinker is itself switching on and off. Making it inactive would probably stop it doing that.
- magicalhippo 5y agoOk, now I'm properly confused. So #Blinker has some code not shown that actually does what the C-like code below does? I assumed active was to turn the GPIO high, given that the code was supposed to implement the same logic. edit: yeah ok I see it now: describe the actual relationship, make that explicit, and instead keep the procedural code that maintains it as a hidden implementation detail.