Skip to content
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

Remove some redundant keywords #880

Closed
wants to merge 6 commits into from
Closed

Conversation

gilch
Copy link
Member

@gilch gilch commented Aug 9, 2015

Ref #240 in the Grand Language Cleanup. This is not enough to close the issue, but it helps. The redundant keywords I am aware of in Hy are:

raise/throw
except/catch
do/progn
defn/defun
lif/lisp-if and lif-not/lisp-if-not
defn-alias/defun-alias

True/true
False/false
None/nil/null

def/setv
lambda/fn
first/car
rest/cdr

This pull request only touches the first group, likely to be the least controversial. The second group may be a bit more difficult to fix. The third group has slightly different behavior/convention, so may be harder to unify.

Removed: throw
Rationale: raise is a Python keyword, and thus reserved anyway. This reduces the number of reserved words in Hy, while the other choice would not. It is also less confusing to Python programmers.

Removed: catch
Rationale: except is a Python keyword, same as above. catch was popular, perhaps because it's shorter, but when choosing between Python reserved words and equivalent Clojure words, Hy must choose Python's words, or redundancy in reserved words remains.

Removed: progn
Rationale: do is shorter, and progn was barely ever used in Hy anyway; Clojure forms are more favored by the community than Common Lisp's.

Removed: defun
Rationale: as above, defn is shorter, used more, and Clojure, rather than CL. (This commit also removes defun-alias.)

Removed: lisp-if and lisp-if-not
Rationale: lif and lif-not are shorter. A weak reason, but had to break the tie somehow. These aren't used that much anyway.

Removed: defn-alias and defmacro-alias
Rationale: After removing the above redundancies, these are no longer required in Hy itself. They are also likely to cause similar redundancy issues in the future, in Hy and elsewhere, thus were bad for the health of the Hy ecosystem.

@algernon algernon added this to the Grand Language Cleanup milestone Aug 9, 2015
@algernon
Copy link
Member

algernon commented Aug 9, 2015

👍, except for defn-alias and defmacro-alias. They're very useful when you're doing - arguably crazy - stuff like these:

(defmacro-alias [condᵉ conde] [&rest cs]
  (with-gensyms [s c]
    (let [[ncs (__subst-else cs)]]
      `(with-monad logic-m
         (fn [~s]
           (m-plus (map (fn [~c]
                          ((apply all ~c) ~s))
                        [~@ncs])))))))

(defn-alias [firstᵒ firsto] [l a]
  (fresh [d]
         (consᵒ a d l)))

Granted, the number of people who do that are few, but when you want to give a function a hy-ish, perhaps unicode name, and still want to allow python people to use it without tearing their hair out, these macros are handy. And fun. I agree they don't have much use, but they aren't completely redundant.

@Foxboron
Copy link
Member

Foxboron commented Aug 9, 2015

I'd also like the alias functions to stay. They are usefull even tho the core lib won't be using them much.

@refi64
Copy link
Contributor

refi64 commented Aug 9, 2015

Just to say: I like having both def and setv: the former is primarily used for globals, and the latter for locals.

@algernon
Copy link
Member

algernon commented Aug 9, 2015

👍 on keeping the setv/def pair. I'd also keep the true, false, null and nil aliases (because I use them a lot, and shift is far away). lambda and fn are slightly different in behaviour, if I remember correctly, but that may have changed.

I also seem to remember there being a slight difference between first/car and rest/cdr, but I may be imagining things.

@gilch
Copy link
Member Author

gilch commented Aug 9, 2015

... defn-alias and defmacro-alias. They're very useful when you're doing - arguably crazy - stuff ...

...

I'd also like the alias functions to stay. They are usefull even tho the core lib won't be using them much.

Maybe I should just move them to contrib. It would keep the core more focused, but you could still import (require) them if you want. On the other hand, it's pretty easy to alias a function even without the macro:

(def firsto
  (defn firstᵒ [l a]
    (fresh [d]
           (consᵒ a d l))))

This way it's clear which is the standard function name and which is the alias.

I feel like there ought to be a similar way to alias a macro after it has been defined, but it doesn't look easy. The defmacro-alias form just rewrites the whole thing using a new name. This approach seems less than optimal.

@gilch
Copy link
Member Author

gilch commented Aug 10, 2015

I'd also keep the true, false, null and nil aliases (because I use them a lot, and shift is far away).

See, I knew the other groups would be more controversial. This pull (so far) only targets the first group, and we don't have to agree to fixing the other two before merging this part.

We can still talk about them though.

As for the second group, I'll admit to using the easier-to-type aliases true/false/nil almost exclusively in my own code, and they're used a lot in Hy proper. But I still think this is extra complexity for marginal benefit.

Even if you're not convinced by the following, can we at least get rid of null? It's hardly ever used, and not easier to type than nil.

Correct me if I'm wrong about this assumption, but Python keywords have to be reserved in Hy, because Hy compiles to Python and can be imported from Python. They don't have to mean the same thing in Hy as in Python, though this can get confusing. def (for example) has a pretty different meaning, but there's no other good meaning for True and False that we could use instead. True/False/None are reserved in Python3. They cannot be assigned to in Python, and it would be problematic to allow this in Hy. Thus, if we have to choose, the clear choice is the Python words.

I am unconvinced by the argument that true and false are easier to type. True and False literals are actually not used as much as you might expect. Sure, Booleans are used all the time, but usually you type in an expression that evaluates to a Boolean rather than forcing one or the other yourself.

The case where Boolean literals get used the most is in testing. If you're testing at the REPL and just need a generic truthy or falsey value, admit it, you're going to use 1 and 0 over even true and false, because it just does not get any easier to type than that.

Unit tests, on the other hand, also serve as a kind of documentation. It's worth making them readable. Now if we decide that it's idiomatic in Hy to use 1/0 for unit tests, then people will be used to it and it will not be considered hard to read. (Many of Hy's unit tests already do this by the way.) On the other hand, True and False are no less readable, and they even stand out more.

I am also unconvinced by the argument that true and false are used all the time. It's a simple one-line fix:

true, false = True, False

The first group in the pull (which we do seem to agree on) breaks stuff a lot harder than this. Yes, the Grand Language Cleanup will break stuff. Best get it over with now. If removing true/false turns out to be a mistake, it will be an easily correctable mistake. If NOT removing true/false turns out to be a mistake, it will only get harder to fix.

There's a better argument for keeping nil, I suppose. This really does get used a lot. None could perhaps be used for something else, but I don't know what. But nil may cause confusion for Common Lisp programmers expecting it to be the empty list. None wouldn't have that connotation. I'd still prefer we be consistent and get rid of nil, but I'd be more willing to make an exception here.

@paultag
Copy link
Member

paultag commented Aug 10, 2015

I'm OK with purging true false null and nil.
On Aug 9, 2015 8:28 PM, "Matthew Egan Odendahl" notifications@github.com
wrote:

I'd also keep the true, false, null and nil aliases (because I use them a
lot, and shift is far away).

See, I knew the other groups would be more controversial. This pull (so
far) only targets the first group, and we don't have to agree to fixing the
other two before merging this part.

We can still talk about them though.

As for the second group, I'll admit to using the easier-to-type aliases
true/false/nil almost exclusively in my own code, and they're used a lot
in Hy proper. But I still think this is extra complexity for marginal
benefit.

Even if you're not convinced by the following, can we at least get rid of
null? It's hardly ever used, and not easier to type than nil.

Correct me if I'm wrong about this assumption, but Python keywords have to
be reserved in Hy, because Hy compiles to Python and can be imported from
Python. They don't have to mean the same thing in Hy as in Python, though
this can get confusing. def (for example) has a pretty different meaning,
but there's no other good meaning for True and False that we could use
instead. True/False/None are reserved in Python3. They cannot be assigned
to in Python, and it would be problematic to allow this in Hy. Thus, if we
have to choose, the clear choice is the Python words.

I am unconvinced by the argument that true and false are easier to type.
True and False literals are actually not used as much as you might
expect. Sure, Booleans are used all the time, but usually you type in an
expression that evaluates to a Boolean rather than forcing one or the other
yourself.

The case where Boolean literals get used the most is in testing. If you're
testing at the REPL and just need a generic truthy or falsey value, admit
it, you're going to use 1 and 0 over even true and false, because it just
does not get any easier to type than that.

Unit tests, on the other hand, also serve as a kind of documentation. It's
worth making them readable. Now if we decide that it's idiomatic in Hy to
use 1/0 for unit tests, then people will be used to it and it will not be
considered hard to read. (Many of Hy's unit tests already do this by the
way.) On the other hand, True and False are no less readable, and they
even stand out more.

I am also unconvinced by the argument that true and false are used all
the time. It's a simple one-line fix:

true, false = True, False

The first group in the pull (which we do seem to agree on) breaks stuff a
lot harder than this. Yes, the Grand Language Cleanup will break stuff.
Best get it over with now. If removing true/false turns out to be a
mistake, it will be an easily correctable mistake. If NOT removing true/
false turns out to be a mistake, it will only get harder to fix.

There's a better argument for keeping nil, I suppose. This really does
get used a lot. None could perhaps be used for something else, but I
don't know what. But nil may cause confusion for Common Lisp programmers
expecting it to be the empty list. None wouldn't have that connotation.
I'd still prefer we be consistent and get rid of nil, but I'd be more
willing to make an exception here.


Reply to this email directly or view it on GitHub
#880 (comment).

@algernon
Copy link
Member

Ok, lets get this rolling: defn-alias / defmacro-alias moved to contrib is a reasonable compromise, I believe, and the rest of this PR is good to go. We'll discuss the other stuff in different PRs / issues (like #240).

@gilch, can you do the contrib move? Or I can merge this as-is, up to the prior commit, and do the move myself.

algernon added a commit to hylang/hydiomatic that referenced this pull request Aug 10, 2015
The throw, catch, progn, defun, lisp-if and lisp-if-not aliases are
going away, as per hylang/hy#880, add rules to grand-cleanupᵒ that
suggest the correct symbol names.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
@algernon algernon closed this in bc81e8c Aug 10, 2015
@gilch gilch mentioned this pull request Aug 11, 2015
@gilch gilch deleted the redundant branch August 11, 2015 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants