
Best Practices for Using Functional Programming in Python (kite.com)
93 points by BerislavLopac 6 days ago | hide | past | web | favorite | 37 comments

is it no thanks I don't want to go to kite.com because they spy or no thanks I don't want programming suggestions from people who spy?


“Both” is better way to put it.

any cloud company is spying for you? google, amazon, microsoft, apple...? you might want to give up hacker news too then...

Here, just use an archive https://archive.fo/ixt4n .. damn.

Is this not the company that put on spyware in a package for Sublime text?

> Kite is a plugin for your code editor that uses machine learning to provide you with code completions in real time sorted by relevance.

The whole article seems to be nothing but a transport vehicle for that ad. Spyware for even more editors.

Well... In my case it keep saying

Huh... that's weird

Something unexpected occurred. We'll investigate what happened

Refresh the page

Anyway, Python actually support limited functional programming so I only get it for that topic :-)

Here's another article on FP in Python for those who'd rather an alternate than go to kite.com.


Edit: After scanning the kite.com article for a second time, I see the author actually links to Mary Rose Cook's article.

How is Kite still in business after telemetry abuse?

Sadly I would not be shocked if they managed to gather additional funding.

Well... If I'm looking for functional programming in python... I'll choose hy (hylang) witch is actually Cython with a lisp-y syntax.

Otherwise if I'm accustomed to Python but feel the need of something functional and scheme/lisp are too hard well... I go for Nim...

Python is FANTASTIC as a simple language to tech programming these days and to glue stuff together, with the benefit of a respectful standard library but frankly if we go beyond we have other options perhaps with some sharp corners (less easy to code, less complete standard library, less documented etc).

Beside python has pretty awful support for functional programming, I don't get what is purpose of this. Is it just a Facebook for developers? Why anyone should use autocomplete sever in others computer? What is advantage of this over other autocomplete API's such Jedi, Pycharm, Microsoft python server, that doesn't run in other computer? I hope these sort of thing's won't become popular.

> Beside python has pretty awful support for functional programming

That seems counter to my experience and understanding of things. Python has adequate support for functional programming. And bonus you can mix in some object oriented things as well.

What Python has, is really good support for procedural programming. You can write pure functions when it makes sense, and you can write side-effecting procedures wherever you want. You have a bag full of useful data structures, and an extensive standard library to hand. Python's biggest drawback for me is that it's what I'd call a "surprisingly typed" language. Values in Python are strongly typed, but we pretend they're not. Until, surprise! AttributeError! That thing isn't what you thought it was. Optional typing has started to help with that.

"surprisingly typed" is a good term. It sounds, though, like you're using it to mean "dynamically typed", which is maybe overly harsh.

What I think it captures well, though, is an unfortunate habit among many dynamic languages' communities to pretend that types don't matter. Python is getting better, but it used to be really bad about this. The standard library's documentation, for example, would give only the names of a function's parameters, and leave it to you to figure out, presumably by guess and check (and prayer), what kind of input it was prepared to accept. It's still really common for the documentation to force you to go to the REPL to ask a function's return value what its type is.

I work in Python day to day and have done for several years, so I think I'm entitled to describe Python's type system as "surprising." I generally think duck typing is great, and I always appreciate the flexibility it gives me. But the flip side of that is -- surprise! -- you can't use me as an index! -- surprise! -- I'm not hashable! -- surprise! -- you can't pickle me!.

I've been looking at how other languages handle this, and I think typeclass / trait systems seem to strike a good balance, allowing flexibility without surprises.

The typeclass approach can be just as surprising. Possibly more so, because it means that a type's implementation of a class can come from literally anywhere. So the universe of surprises still includes "Surprise! It's not hashable!", but now also includes, "Surprise! It was hashable, but now isn't, because you stopped importing this seemingly unrelated package."

If you do get surprised that X doesn't support Y, though, you have ability to provide your own implementation without resorting to monkey patching.

That's a good point! I suppose the grass is always greener...


Strongly typed? Maybe you mean statically typed?

From "What To Know Before Debating Type Systems"[1]:

"Probably the most common way type systems are classified is "strong" or "weak." This is unfortunate, since these words have nearly no meaning at all..."

[1] - http://blog.steveklabnik.com/posts/2010-07-17-what-to-know-b...

No, I don't mean statically typed. Python is dynamically typed. But it's typed nonetheless, and types in Python matter way more than it appears at first glance. There's no such thing as an untyped value in Python. This is the opposite of C, which is statically typed, but where void* opens the door to doing great and terrible things. I guess you could also call C's type system "surprising", except the surprises aren't cute and annoying like Python's. C's type system is surprising like being defrauded by an accountant is surprising -- everything seems fine for years, and then it all falls apart.


- Use pure functions

- Avoid mutability

- Limit use of classes

- Strive for idempotency

- Use lambdas and higher order functions sparingly, only when they actually simplify the code

- Use generators where applicable

All in all, it's good advice which shouldn't be ignored just because she works at kite.

She should probably go back and proof read the article and fix the code and terminology errors, though.

But generators are inherently stateful and don't have referential transparency because of their consumption semantics.

You can't get away from using state in Python because it lacks TCO.

Python doesn't even have tail call recursion optimization (you'll hit a RecursionError exception if you go too deep).

Using first-class functions is great but I hesitate to call any serious use of Python "functional programming".

Many Common Lisp implementations also lack TCO.

That said, I do agree that you probably shouldn't go crazy with FP in Python. At its core, it's a procedural language. It has some useful things from OO and FP, but you'll be more comfortable if you keep procedural techniques in the top tray of your toolbox.

Which isn't all that bad a thing. IMO, well-done modern procedural programming looks a lot like functional programming with more loops and less recursion.

Common Lisp is one of the least "functional" of the major lisp dialects too. Without TCO you generally need state for iteration.

That being said, I agree, there's nothing wrong with taking aspects that you like (first-class functions mainly) without having to be a purist. In fact, imo purely functional languages are tedious compared to procedural languages like Python.

That said, the ML/Haskell-like functional languages do have one thing that most procedural languages do not, which is that they help you keep side effects under control.

I'd like to find a procedural language that allows for side effects (it is still procedural programming, after all), but encourages keeping them under control. I've been toying with Nim lately, and it's been a good experience. I think that it's possible to do even better, but it's already way ahead of anything else I've tried.

You can hack that in with a decorator if you’d like, at some cost to performance.

Adding FP features to an otherwise-mutable language has always seemed a mixed bag to me. Obviously it’s nice to have those features, but you don’t get the immutability constraint that makes development so much more predictable.

Python offers immutable data structures in addition to the mutable ones. Tuples are immutable, we've had namedtuple for a while, and now it's possible to write immutable data classes as well. As time goes by, I find myself using less and less mutability in Python. At this point I default to immutable structures, and I bring in mutable ones only if I need them for performance or there's no reasonable immutable alternative.

Tangentially, I was extremely annoyed to discover that tuple unpacking in function headers was removed with Python 3. Coming from Erlang, tuples were quite appealing, but that was frustrating.

Not true at all! Coming from Java, notoriously OOP heavy idiomatically, or python, sprinkling in some functional programming is Fantastic(!). Despite all the FP vs OOP hoopla I think they actually play fairly well together. Even OOP has moved to immutable records + localized behavior as the rule and fully mutable objects with side-effects are the exception.

FP is great at the high-level for orchestrating workflows and in the lower-level processing/transforming/aggregating over streams of immutable records. OOP is great at the high-level for independent communicating services/life-cycles and fine-tuned memory bound algorithms and needing state machines lower down.

You generally know what parts of your code mutate and what don't well enough to get the nice side-effect free usage from your functional parts.

Someone smarter than me once said: OOP? FP? It's really all just about being principled about state. A closure is just an object with one function.

You can get those OOP benefits using Erlang.

I’m not saying it’s bad to add FP bits to other languages. I just haven’t seen the same benefits as when I know what a called library/module can and can’t do with my data.

Exactly this. In Haskell, I can look at a function signature or definition and be guaranteed a lot of what that function is or is not able to do without needing to look at the code it's calling. That's never going to be the case with Python. I can only, at most, trust the conventions the writer seems to be following.

Indeed, "Mostly functional" programming does not work: https://queue.acm.org/detail.cfm?id=2611829

i understand who the author of that article is, but i feel that's an overly hardline approach. f# and racket are perfectly fine and productive mostly functional languages.
