Hacker News new | past | comments | ask | show | jobs | submit login
Pointfree style in Python (markshroyer.com)
104 points by Niten on Nov 14, 2011 | hide | past | favorite | 32 comments

I like the concept in principle (being a fan of Clojure and in particular its threading macros), but I'm not sure this is something I'd ever use. Breaking language idioms and creating challenges for code readability for future maintainers doesn't seem to be worth the gains in novelty.

However if these semantics were brought into the core language I'd be very happy.

(I'm the author of this module.)

Yeah, I admit part of me felt dirty implementing this by commandeering operators. But my brief time with Haskell and F# has biased me enough toward this style of function composition that I preferred to deal with the ugliness of my hack, rather than the ugliness of not being able to express certain functions in this style in my other toy projects. :)

I agree though, hopefully the language itself will support this one day, and then my ugly hack can go away. (I swear, Python always seems to stop just shy of being a fantastic little dynamic fp language...)

Thanks for the feedback!

Trust me I am right there with you; Haskell does a lot of really beautiful things. Python lifted its list comprehension syntax from Haskell, as a matter of fact. It is only that I consider it a core responsibility of programmers to take into consideration the poor sap who has to maintain their code once the original author gets hit by a truck or eaten by a shark.

> hopefully the language itself will support this one day, and then my ugly hack can go away.

+1 here, but I'm not holding my breath. Python's BFDL has been hostile to making lambda more powerful; I'm not sure what he would think about this.

I think the syntax is fine. The star operator already is sensitive to the operands, so you're not impairing readability at all.

I'd really love to see an operator for this in Python as well. I feel it's lacking.

Python's an object-based, highly dynamic, systems language. It's got a big set of builtins, a relatively large standard library, and is based around iteration and composition. It's not what I would consider a "little" or "fp" language. Sure, you can write pure, referentially-transparent units in Python, but sometimes you have to write things that set! attributes, and that's just a part of life.

Overloading these operators on function objects really isn't the end of the world. It's not like these operators were being used for anything, and sometimes this kind of DSL-ish extension can be good. It's certainly more reasonable than the goto module, which uses horrid bytecode hax to get the job done.

If you want this in the language, write to the python-ideas mailing list, and then draft a PEP if you get any support. Good luck!

It's a super neat hack; but if you use it in production you're completely crazy. I think it's intended that way.

Why is it crazy to use it in production?

There's going to be a lot of overhead with this kind of thing, but did you have another reason?

The simple answer is, go look at @partial's __call__: https://github.com/markshroyer/pointfree/blob/master/pointfr...

All that code is executing on every partial call. So, a very brief list of reasons not to use this in production:

1. overhead

2. complexity

3. debugging

4. don't fight the language

edited to add: I just want to emphasize that I think it's a really, really neat hack!

Because it deviates entirely from Python's semantics.

edit: In other words, "Don't fight the language" as another commenter said.

Interesting comment. It made me think how Lisp programmers spend their time extending their core language every time they use a macro. Does it mean that Lisp programming is about creating challenges for code readability for future maintainers? To be honest, I think Lisp programmers are just a different breed entirely.

Lisps are unique in their lack of syntax. Not fit for comparison to any other type of language. When you use a lisp language you know exactly what you're buying into.

I wrote an ETL thing recently based on generators. It's quite similar in concept to the paper[1] that David Beazley wrote (without ever hearing about the paper though). Source's available at https://bitbucket.org/saalaa/sauceboat

When I'll have time, I'll implement a web WSGI Web UI to provide visualization capability. My goal is to provide a programmer-friendly replacement to Pentaho Kettle.

[1] http://www.dabeaz.com/generators/Generators.pdf

I'd like to hear more about this. I'm working on a javascript CSV reader that displays parallel coordinates + a data grid:

http://exposedata.com/parallel/upload.html http://exposedata.com/parallel/ (if upload fails, this is what it looks like)

Once I get the CSV uploader more robust, I'll add additional charts that respond to interactive filters/aggregators, just as the table responds to the chart above.

The goal is a data exploration tool for non-programmers, but I'm keen to extend it for programmers who need more sophisticated ETL and are willing to do a little scripting.

I'm not sure you should provide ETL capabilities.. Usually, ETL and visualization are separate steps in the workflow and sometimes even in a team. If it's too limited in scope it won't be very useful anyway.

I appreciate the beauty of the pointfree style but whenever I tried to use it I found that I couldn't read my own code the next day. It seems that my brain is just hard wired to expect a list of parameters in a function definition.

EDIT: That is, all these years at school I was taught to write f(x) = x^2, not f = (^2).

I don't think a Haskeller should try to use point-free code. It's just that if you're refactoring your code and you get it down to the point that you've got

   thing x = th . in . g x
you might as well finish the job and take the x out. What's left should make sense to you if you follow this process and just let it happen. But I feel no shame when I can't go pointfree, especially when pointfree requires crazy hacks to simulate a simple pattern match.

Sorry, but, aside from the obviously unimportant use of `in` (a reserved word), this gives a different type from what I think you meant:

    x :: a
    g :: a -> b -> c
    in :: c -> d
    th :: d -> e
    thing :: a -> b -> e
and naïve eta-conversion will give you something that isn't well typed. Probably you meant

    thing x = th . in . g $ x

Yes, thanks.

They should have told you write f = (x -> x^2) or so.

I think it's better pedagogically just to acknowledge that, in common mathematical discourse, "the squaring function" doesn't have any symbolic name. Perhaps it's more illustrative to think of, for example, `f(x) = ln(x)` (the value of a function) versus `f = ln` (the function itself); and a good (college) mathematics teacher will make this distinction.

They could also tell me to write (= f (-> (x) (^ x 2))). Then we would all be using lisp and laughing and those few developers who would using that weird infix notation.

While I like S-Expressions for computers, even in that small example the parenthesis are a bit excessive. Keep in mind that mathematics is mostly written by hand on a black board.

Ah, so it's postfix you want?


On a blackboard I want to (ab)use that I have a nice and flat surface, and don't have to be restricted to linear strings of characters.

You know an agreeable (not quite sure about good) idea when you realise that something you've been implementing yourself has been done by somebody else better.


Reminds me of Pipe[1]

[1] http://pypi.python.org/pypi/pipe/

It's a neat trick, but why not just use Haskell?

IMO, point free style is hard enough to understand in Haskell code, where it's used all the time and I'm expecting to see it. Coming across it in Python, where I'm not expecting it, would probably take me an hour just to figure out what you were trying to do.

yeah, I agree, use python in the way it was meant to be used. If you're dying in python because it's not as cool as Haskell, but you need to use some existing python code, it's not that hard to run a Haskell program as a child process of python or vice-versa.

Besides, you're not able to do all the point free stuff in python, you can't partially apply an infix function (there is no `map((+2), [1, 2, 3])`.

You can, it just looks like this:

map(functools.partial(operator.add,2), [1, 2, 3])

How is this better than attaching data to objects and operating on them with its methods? (Seriously, I would like to know). The syntax does not look all that different and with classes you can additionally have inheritance by which you can "get" a lot of relevant methods for free...

The term "pointless programming" sounds much more fun.

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