Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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?


> 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 completely different type from `String`, so the type checker can and will enforce that they don't improperly intermingle.

> and b) not call f with invalid parameters?

Same story here. If f takes a String argument, you can't (deliberately or by accident) pass it a Maybe String instead, or your code simply won't compile. The strong static type system in Haskell eliminates the mental burden of having to always watch out for nulls and handle them as a special case.

That may not seem like much of a burden if you're accustomed to languages like Python, Java, etc. where nullability is the default. But think about how much time you've spent dealing with NullPointerExceptions (or the equivalent in your language of choice) and imagine how much nicer it would be if the language itself could simply eliminate the possibility of them ever occurring in the first place. Well, thanks to its type system, Haskell can do that.


I agree, but that particular issue can be fixed with a type system tweak instead, to treat nullability as a type modifier, vaguely like constness, which can then be statically enforced. Cyclone adds nullability annotations to C, for example, and Ada has a "null exclusion" type modifier.


The advantage to Haskell's type constructor approach, though, is extensibility. Making nullability a language keyword like `const` requires a change to the fundamental grammar of the language. In Haskell, `Maybe a` is just another data type, defined entirely in Haskell itself. This opens the door to allowing users of the language to create arbitrary type system constraints without having to modify the compiler to support them.


Python doesn't have nullability, you must always pass some object; None is just an object like any other /pedant.


I'm not asking about haskell though, I was asking what the valid reasons for that python code being written.


I'm pretty sure that the author of the article didn't mean to imply that you should actually define monads explicitly in Python and start using them in your code. That would be inelegant, far from idiomatic, and mostly pointless, since Python doesn't type-check your code like Haskell does, and most of the advantages of an explicit Monad class arise from its usage in the presence of a strong type system.

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.


Wouldn't coding defensively just end up looking like:

   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.


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.


Moving away from the trivial example used for simple demonstration purposes...

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?


It's a workaround for Python not being able to type-check, compared to Haskell.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: