-
Notifications
You must be signed in to change notification settings - Fork 370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Anonymous function literals. #879
Comments
I like the idea... ...but doesn't Hy already have enough syntactic sugar (e.g. |
I wouldn't call that sugar so much as pointless aliasing, which I was hoping to get rid of per #240. Maybe I should just make a pull request for that to get the ball rolling. Removing stuff seems a lot easier than adding it. |
Not really. Once you add it, there's a good chance that removing it will break code. Of course, Hy is still in beta, so code breakage is "technically" ok, but it should still be avoided when possible. |
Also, one person said this about Clojure's lambdas:
:/ |
After playing with Iverson's J, Clojure's anonymous function literal doesn't look so bad to me. But the example you linked to isn't a fair comparison, Clojure's equivalent lambda actually looks like this: (fn [x] (+ 1 x)) The Is this version |
|
Why, oh why, do we need syntax for anonymous functions? lambda is perfectly fine and legible. From one perspective I understand that “lambda,” is so common that like “quote,” “unquote,” and friends it perhaps deserves syntax in order to keep readers from being distracted by mundane details. However the same could be said for “defn” or “defmacro” and others. Unlike “quote” and “unquote” I think “lambda” isn’t just noise but like “defn” and “defmacro” it defines a new form and deserves to be spelled out. If it’s too much to type, write a reader macro or learn to use your text editor.
|
Being in the middle of the Grand Language Cleanup, I like @agentultra's suggestion best. 😆 |
It's not unusual for a programming language to substitute ASCII digraphs for other characters not easy to type, so
Why, oh why, do we need a Hy? Python is perfectly fine and legible ;) "Need" is a relative term. One may as well ask, "Why does Clojure need A major use case for this syntax is partial function application with a minimum of ceremony. This is something one uses quite a lot when writing code in the functional style, especially in a language that does not have automatic currying. This is so important that Python added
Yes, and Java's tedious verbosity is made much more tolerable with a good IDE. Any language you have to excuse via editor has serious issues. A good Lisp should need little more than parentheses-balancing and indent support. I'm surprised by the lack of enthusiasm here. I do understand (and support) the need to guard against cruft in the language, but this can be taken too far in the other direction. After all, Hy is a Lisp, and if some things are missing in the language, the user will add them. With macros, if necessary. (Like how I just added a macro for function literals.) If a standard is too minimal for too long (e.g. Scheme, Lua), then the community will fragment because everybody has to re-invent the wheel, but they all do it independently and in incompatible ways. Hy avoids a lot of this kind of problem by supporting Python's libraries, just as Clojure does with Java's. But Clojure still has both |
I just feel like you save just a few characters for little benefit, and it's harder than it looks to compile. You can't just recurse through the AST: (,\ (x ,1 (,\ ,2))) ; (fn [a] (x a (fn [_ b] b)))
(,\ (,\ (,\ ,3))) ; (fn [] (fn [] (fn [x] x))) Also:
Very true (I hate Java :). However, then you also have the APL extreme, which produces an insanely weird programs, like (in K):
Language design is all about compromise, really. |
How would people feel about |
I'd be okay with
Now that I'm thinking of it, if we do indeed go down the "make it a unicode symbol"-path: what do math people use to denote a parameter? My first intuition would be something like λ1, λ2 (think eigenvalues) or μ1, μ2, etc. |
They don't support nesting! Neither does Clojure's. This was never meant to replace lambdas altogether. And I have a working macro. It might be improved by error checking, but it does work. |
It’s entirely possible to use Java without an IDE. You just wouldn’t want to. I could use an editor as you described for Lisp development but I wouldn’t want to when I have emacs + slime + paredit. The bar is much higher than you think. Java’s legendary verbosity is the least of its problems. Text editors take care of managing text for you. The good ones do anyway. The problem I have with introducing Clojure’s syntax for LAMBDA is that I find it superfluous for the following reasons:
|
+ Evil 😈. I do appreciate a good editor. But if you find that you're tempted to write a new emacs function to help you with writing repetitive/boilerplate Lisp (like IDEs do for Java), you're better off writing a macro so it's not repetitive instead.
We already have Clojure's syntax for LAMBDA! It's spelled "
We can put the
Parsers general enough to support macros will support this macro too. Hy does use macros. A lot.
Oh, I agree syntax should be kept as simple as possible... but no simpler. Hy has an entire contrib section dedicated to anaphoric macros, and even has |
I still don't understand the benefit this would bring to Hy. I know Clojure. I still don't see the appeal or the benefit it brings users. As near as I can tell fn and lambda being aliases for the same thing is redundant and worth cleaning up. I'd be more in favour for making better reader macros. Then this discussion would be moot. We could just have lambda and those who think syntactic short-hand improves their programs can run off into the woods and be merry. Sent from my mobile
|
👍 to just using reader macros as the short-hand. |
Agree with this part, though they don't behave exactly the same now. I would be in favor of removing
I'm not certain we're even talking about the same thing at this point. You seem to be saying that you're not in favor of adding an alias for lambda like, But this is not what is being proposed here at all. I'm suggesting an anaphoric macro like the I really don't know what |
I asked around and did some reading, but didn't find anything that would universally be used to denote a generic parameter. Parameters tend to be given descriptive names (be it x, y, z or something else) that are dependent on the given case. λ1, %1 or $1 don't look too bad to me, but I'm open for other ideas. |
I see what you're saying now. Perhaps it'd fit nicely in hy.anaphoric If it took this amount of discussion to get the point across there's no sense confusing new users. We don't need confusing syntax for lambda which ever way we cut it. Sent from my mobile
|
It's honestly not confusing. Clojure uses this to a large extend on map/filter/reduce user=> (map #(+ %1 10) [1 2 3])
(11 12 13)
user=> (map (fn [a] (+ a 10)) [1 2 3])
(11 12 13) In my experience it reduces the verbosity on smaller operations. |
It’s not confusing to someone already familiar with it. They’ve already committed it to memory. Perl is very effective for people who’ve internalized its idioms. It’s initial curve is rather wonky. If we just want to re-implement Clojure on Python there are better ways to do it. It seems to me that this discussion is starting with a foregone conclusion. Why is this useful for Hy? (ap-map (+ it 10) [1 2 3]) What’s the win here for adding this special syntax? I think we can just put it in the hy.anaphoric package and those who like it can use it.
|
👍. Having it in core seems to be a bit overkill indeed. We'd still need to decide on a syntax though. I like @gilch's idea with |
These do indeed fix the verbosity problem in the particular cases of map and filter. And the other The biggest win is for partial function application, as I mentioned before. You need this all the freaking time in functional programming. That's why pure functional languages like Haskell automatically curry their arguments. For example, in Haskell, if you define something equivalent to the Python It's never going to be that automatic in Python, but this capability is important enough that Python got functools.partial in PEP 0309. To make this anywhere near as usable as auto-currying, the syntax must be as short as possible. Clojure's form is good enough, but But an anaphoric lambda is even more general than this. It's very common in functional programming to create a pipeline of lazy generators by composing functions. For those who use Unix derivatives, this is very similar to the pipelines one would build in a |
We don't have to use a prefix, though maybe we should. Our Actually, this reminds me of something from my linear algebra course. Vectors of up to four dimensions sometimes used What do you guys think of that? |
This argument isn’t going anywhere because of that foregone conclusion I had mentioned. I know what all of this stuff is and I get it. It still doesn’t answer why Hy needs it. Why does this have to go in core and not in a contrib module? I’m not saying it isn’t useful I just don’t see it being useful in core. Python is not a functional programming language and probably never will be. And it’s not terribly hard to write a module with curry, compose, bind, etc as I did for a monadic parser combinator library I wrote to replace our dependency on rply. |
Oh, neat. x1, x2, xi and so on would work I think. If we wanted to be fancy, could even use x₁, x₂, etc. as aliases.
Sounds like a plan to me. If it gets super popular and users start complaining about |
You don't need a pure functional language to use the functional style. Just like you don't need an object-oriented language to use the object-oriented style. GTK+ is a great example of object-oriented C. Python supports multiple paradigms. It has lazy generators (yield, genexprs, itertools), higher-order functions, and functools. I use functional style quite a lot in Python. Lisp is not a functional language either, but it is very multi-paradigm, and Clojure in particular tries to support functional style well. Hy inherits quite a lot from Clojure, thus I assumed supporting functional style with Clojure idioms was a design goal for Hy. No, we don't have to put it in core. Consensus seems to be, put it in anaphoric and not in core, at least for now--answers one of the main questions I asked in the OP, "would you prefer I put it in core or contrib?"
OK, I'll try to put together a pull using the |
Preaching to the choir, good buddy. I’ve been working on and off on a monadic parser combinator library to replace our dependence on rply. Hopefully get us to Hy in Hy. You can program in a functional style in Python. Python will probably never curry functions.
Sweet
|
I believe it's possible to set up vim/emacs to render it this way. This is probably a cleaner solution than supporting it directly as aliases in Hy, which is also possible, but would complicate the macro a bit. We could even use The digit subscripts |
xi-forms are merged and working. Try them out. Was anaphoric the appropriate location? Do we need the Unicode aliases in Hy? Did you notice any bugs? Is the documentation on xi confusing? If nobody speaks up about further changes in a few days, then I'm going to close this issue. |
Yep, I pushed a change that does this to |
Is there any interest in adding something like Clojure's anonymous function literals (e.g.
#(+ %1 %2 %&)
) in Hy? I've got a working macro for my own use, so it wouldn't be hard for me to add it to Hy.We may want to preserve the
#(
reader macro for genexprs per #867. Possible alternatives are a reader macro%
like#%(+ %1 %2 %&)
or an ordinary macro,\
like(,\ + ,1 ,2 ,&)
.If you want it, would you prefer I put it in core or contrib?
The text was updated successfully, but these errors were encountered: