Earlier quoted context omitted.
wouldn't it be better to a) code f defensively in the first place, and b) not call f with invalid parameters?
> wouldn't it be better to a) code f defensively in the first place, In Haskell, you don't have to. If your function takes a String as an argument, for instance, the compiler will ensure that it never receives a null instead. It will always receive an actual String, because normal types are non-nullable in Haskell. You have to explicitly wrap a type in a Maybe if you want to add nullability, and `Maybe String` is a c…
The Day Python Embarassed Imperative Programming
61–70 of 80 posts
Re: The Day Python Embarassed Imperative Programming
#62Perhaps the author is just glossing over the bigger picture for the sake of explanation, but it's a bit of a narrow view of monads to say that they are just "conditional function calls". That's true if the monad in question is Maybe, Either e, or (if you're squinting at it just right) []. But >>= in the State s and IO monads, for instance, has little to do with conditionally calling functions; there, it's more about…
m a -> (a -> m b) -> m b Okay, so what does this mean? I thought it was `f x -> x * x` is a function definition, right? Or am I completely mistaken here? Because in the above code, what is the function name, the parameter and the return value? I know "everything is a function" in Haskell but I really can't see through the multiple arrows here. Any help?
Re: The Day Python Embarassed Imperative Programming
#63Earlier quoted context omitted.
One could say the problem is using None for indicating errors. Python does have exceptions, which also prevent further statements from being executed. try: b = f(a) c = g(b) return h(c) If f(a) raises an exception, g and h don't get executed. None should be returned when it's a valid value (say, in search() if it doesn't find anything), and in those cases it makes sense to have explicit handling.
That's a fair point. On some level a try block resembles a monad that encapsulates success/failure. However, it is not general, e.g. it does not provide a solution if you want to chain computations where returning None/Nothing is valid (e.g. a Map lookup in Haskell). The nice thing about monads is that it provides an abstraction on sequences of computations, involving failure, error, state, effects, etc. Though, it c…
But I think that's a feature, not a bug. Conflating errors and valid values leads to ambiguity. As PEP 20 says, "Explicit it better than implicit".
If you actually want certain function return values to act as a failure, I think you should wrap it in a new function that adds those semantics.
Re: The Day Python Embarassed Imperative Programming
#64Perhaps the author is just glossing over the bigger picture for the sake of explanation, but it's a bit of a narrow view of monads to say that they are just "conditional function calls". That's true if the monad in question is Maybe, Either e, or (if you're squinting at it just right) []. But >>= in the State s and IO monads, for instance, has little to do with conditionally calling functions; there, it's more about…
m a -> (a -> m b) -> m b Okay, so what does this mean? I thought it was `f x -> x * x` is a function definition, right? Or am I completely mistaken here? Because in the above code, what is the function name, the parameter and the return value? I know "everything is a function" in Haskell but I really can't see through the multiple arrows here. Any help?
http://conal.net/blog/posts/everything-is-a-function-in-hask...
Re: The Day Python Embarassed Imperative Programming
#65I read the article and I still don't understand what monads are about. This happens every time. There must be something about the Haskell syntax (which has been ages since I used it in college--and I utterly failed to grasp monads then, too) it's very frustrating, I get the rest of functional programming. Apparently I forgot how to read Haskell.
Its not the syntax, its the concept that's hard. I read about 10 different monad tutorials, and it only made things worse. The only thing that made it click was writing code that used them. (Some monadic parser code.) Seriously, reading monad explanations is like struggling in quicksand of abstraction. Only by making it concrete in working code did I make any progress. If I had to pick the most tractable monad, I wou…
Re: The Day Python Embarassed Imperative Programming
#66Earlier quoted context omitted.
> wouldn't it be better to a) code f defensively in the first place, In Haskell, you don't have to. If your function takes a String as an argument, for instance, the compiler will ensure that it never receives a null instead. It will always receive an actual String, because normal types are non-nullable in Haskell. You have to explicitly wrap a type in a Maybe if you want to add nullability, and `Maybe String` is a c…
I'm not asking about haskell though, I was asking what the valid reasons for that python code being written.
The example snippet was likely just an illustrative example, using Python merely because it's a more widely understood language than Haskell. If he wrote it in Haskell, then not only would it be redundant (since monads are already defined in that language), but it would be less comprehensible to the intended audience of new and non-Haskell programmers.
Re: The Day Python Embarassed Imperative Programming
#67Earlier quoted context omitted.
"Learn you a Haskell for great good" is probably the most approachable book on the subject you can read it online for free. People who are confused should definitely check it out.
Yes, it is by far the best way to learn what monadic really means. http://learnyouahaskell.com/chapters is the book, but if you already understand basic Haskell syntax, you can start at Chapter 11, Functors: http://learnyouahaskell.com/functors-applicative-functors-an... Yes, it's a bit long, but it actually works, and, what's more, unlike the vast majority of monad tutorials written by someone who just sort of half…
Re: The Day Python Embarassed Imperative Programming
#68Would it be possible that there are no blind spot on the Python side and a "semantic golden hammer" (for the lack of a better term) on the Haskell side? I'm not being sarcastic or anything, I'm really wondering: are Python programmers using monads without knowing it? Or is it that monads are a good tool at giving a semantic (or "mathematical meaning") to what they are coding? I think the distinction between the two p…
Well, that's the idea of monads -- you can see them everywhere because their original purpose is to express imperative programming mathematically. It's like thinking that all numbers can be represented with digits; of course -- digits were invented to represent all numbers. But the thing that makes Haskell unique is not that you have explicit monads. It's that you can (1) use monads other than the IO monad (like Mayb…
Re: The Day Python Embarassed Imperative Programming
#69Earlier quoted context omitted.
You wouldn't want to call f directly if it doesn't accept None . pymon is a function meaning f(v) if v else None .
wouldn't it be better to a) code f defensively in the first place, and b) not call f with invalid parameters?
def f(v):
if v is None: return
# REST OF f stuff
And say you have other functions g, h, i, ... each one of those would also start with the: if v is None: return
portion of the function. This is just a case of DRY.Re: The Day Python Embarassed Imperative Programming
#70Earlier quoted context omitted.
No? The point is to factor out the repeated check-for-None code into one place to reduce redundancy and unclutter the algorithmic code in f. Separation of Concerns.
Writing wrapper functions that just calls a function provided as an argument seems insane to me. If the code really cares what it's getting, it should not only be checking for None, but also that the arguments it is called with are valid. I still fail to see why you would write a function like this at all.
Have you ever written validator code for your inputs from a web form? It really is the same pattern, usually implemented via decorator rather than direct
result = validate(f, inputs)
calls, but decorators are just syntactic sugar for that.Or are you really suggesting that every function which may take data from an input source copy and paste the same validation code to the top of that function?