Why the hyphen in methods syntax?

123 views
Skip to first unread message

Sebastian Porto

unread,
Nov 11, 2013, 6:26:00 PM11/11/13
to pyret-...@googlegroups.com
Pyret looks interesting, but something that caught my attention was the convention of using hyphens in function names e.g. fun animal-name
Why don't adopt a more mainstream naming convention like snake case e.g. animal_name ? Or do the underscores have a meaning in pyret?
Could it also be confusing for users having something like: three-two() is that call function three-two or subtract two() from variable three?

Thanks
Sebastian

Goodman, Frank

unread,
Nov 11, 2013, 6:43:21 PM11/11/13
to pyret-...@googlegroups.com
I believe this naming convention is inherited from Scheme/Racket. Underscores are used in cases statements and in currying. For example:

_ + 5 is equivalent to fun(x): x + 5;
and
[[1,2,3],[4,5,6],[7,8,9]].map(_.first) is [1,4,7]

and

cases (List) my-list:
  | empty => ....
  | link(_, _) => ... we don't bind the first or rest of my-list to anything, because we use _ in place of an identifier name ...
end

To help avoid confusion with expressions like three-two(), we require spaces between binary operators and their operands (such as three - two()).


--
You received this message because you are subscribed to the Google Groups "Pyret Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyret-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Joe Gibbs Politz

unread,
Nov 11, 2013, 6:48:08 PM11/11/13
to pyret-...@googlegroups.com
Hi and welcome to the list!

We just couldn't give up on how pleasing hyphens in identifiers are to
the eye and the shift-finger. The minus operator in Pyret (and very
soon, all operators) will require surrounding whitespace, so this
isn't ambiguous and will soon be nicely uniform. We can then work on
these error messages to make sure that they guide users towards the
right fix.

Anecdotally, no one in our courses has complained about this potential
confusion, and students do tell us when they run into problems. So we
haven't run into issues with it yet, but this is far from a
comprehensive laying of fears to rest. We should have more
information from our data at the end of the semester about how many
times folks actually ran into this (even if they didn't report it to
us directly).


On Mon, Nov 11, 2013 at 6:26 PM, Sebastian Porto <sebas...@gmail.com> wrote:

Luqi Pan

unread,
Nov 11, 2013, 9:29:13 PM11/11/13
to pyret-...@googlegroups.com
I think I've read it somewhere else but I forget where: another reason is that hyphen is easier to input. If using underscore, you have to use shift+'-' to input it. Hyphen makes it a little bit easier.

One problem that I run into is that I get so used to hyphen in identifier names that I keep doing so in other languages hence producing strange errors. :)

Shriram Krishnamurthi

unread,
Nov 12, 2013, 7:22:02 AM11/12/13
to pyret-...@googlegroups.com
This was one of the syntax design decisions on which we decided to
take a strong position.

On the one hand, we really like the naming system of Lispy languages.
On the other hand, we don't believe one needs to admit the entire
s-expression symbol syntax: in particular, it includes too many
characters that we might want to have be significant. The thing we
really liked from that notation is the dashes in names.

Dashes have a few virtues.

- They lead to pleasant names
- They get rid of the "CamelCase or under_scores" debate (without
precluding either)
- They don't require a shift key, which the other two conventions do need
- They tend to have less ambiguity, especially compared to CamelCase
("XMLRPCRequest" or "XmlRpcRequest"?)

As someone else pointed out, there are virtually no naming scheme
arguments in Lispy languages. I believe that's in large part because
we have dashes: you use lower-case names and dashes -- unless you have
a good reason to choose otherwise, in which case it'll be obvious --
and you're done with it.

I genuinely believe most people never even notice this feature, which
I think is to its credit. Sure enough, virtually nobody asks, "if I
can write a-name, how do I make sure that's an identifier name and not
a minus name?" I believe that's because of how naturally dashes read.

The price to pay for this is to make subtraction unambiguous. As you
have probably noted, we have a simple solution: surround it (and all
binops) with spaces. This, I believe, has other readability
advantages. In particular, as an arithmetic expression gets large, the
additional whitespace will force you to break it up into smaller
pieces and give meaningful names to each of them, which will in turn
improve readability (I conjecture).

Hope that helps explain where this came from.

Shriram

PS: What Frank said is confusing. It's only a *stand-alone underscore*
that implies currying.

Sebastian Porto

unread,
Nov 12, 2013, 7:27:22 AM11/12/13
to pyret-...@googlegroups.com
Yes, thanks for all the replies, makes a lot of sense, for me coming from languages that either user camel case or snake case using dashes seems like an odd choice, but it is just a thing of getting used to it.

cheers
Sebastian

12 November 2013 11:22 pm
12 November 2013 1:29 pm
I think I've read it somewhere else but I forget where: another reason is that hyphen is easier to input. If using underscore, you have to use shift+'-' to input it. Hyphen makes it a little bit easier.

One problem that I run into is that I get so used to hyphen in identifier names that I keep doing so in other languages hence producing strange errors. :)



--
You received this message because you are subscribed to a topic in the Google Groups "Pyret Discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pyret-discuss/rPe7gYBLdPs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pyret-discus...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
12 November 2013 10:48 am

Shriram Krishnamurthi

unread,
Nov 12, 2013, 7:30:54 AM11/12/13
to pyret-...@googlegroups.com
In particular, tell us how it's working out after two weeks. For that matter, whether you even notice!

Kartik Agaram

unread,
Nov 12, 2013, 1:18:55 PM11/12/13
to pyret-...@googlegroups.com
> we don't believe one needs to admit the entire s-expression symbol syntax; it includes too many characters that we might want to have be significant. The thing we really liked from that notation is the dashes in names.. The price we pay for this is to surround subtraction (and all binops) with spaces.

I can't resist plugging my little toy language which makes almost exactly the diametrically opposite set of design choices: http://akkartik.name/post/wart. It's a lot closer to lisp, desugaring entirely to s-expressions, but it supports extensible infix operators with a single hardcoded precedence rule: ops surrounded by spaces are lower precedence than ops not surrounded. The price I pay is that dashes live in 'operator' space and can't be used inside regular symbols.

(n * n-1)  # does what you expect

(I used dashes in names for years and still mourn their passing :)

Shriram Krishnamurthi

unread,
Nov 12, 2013, 2:35:27 PM11/12/13
to pyret-...@googlegroups.com
Hi Kartik -- I have tried just about every possible experiment to stay
closer to Lisp, including even the one you have in Wart. None of them
scaled well *for me*. Ultimately, also, I am totally unconvinced about
the idea of having an identifier named e^i*pi-1 for anything other
than cute illustration purposes. Since *surface* syntax is designed
for humans, I think a compromise between expressiveness, readability,
and predictability is a good way to go.

Shriram

Kartik Agaram

unread,
Nov 12, 2013, 6:51:08 PM11/12/13
to pyret-...@googlegroups.com
Thanks, I'd love to learn more from your experience.

In case it wasn't a typo: e^i*pi-1 couldn't be an identifier, only a compound expression.

My hardcoded precedence rule basically makes it obscene to use infix for more than two layers of precedence, forcing me to either say (e^i^pi - 1), or to revert to prefix: (- (e ^ i*pi) 1).

I don't think anybody would disagree with the need to pragmatically trade off expressiveness, readability and predictability. The deeper philosophical difference here is that I tend to deemphasize worst-case examples of what could go wrong with any feature. We've spend decades now (millennia if you include non-software bureaucracies) trying to separate good states from bad using rules, but rules are straight lines, and good and bad states are fractally distributed throughout the state space. Humans will find ways to screw up no matter how many rules you add. Better to try to teach them the taste of when to create rules and when to break them. I'd rather ignore this entirely in our designs, and rely on some out-of-band social process to teach taste.

Both approaches are probably tilting at windmills. But I know which windmill I'd rather tilt at :)

This is mostly a rant against languages like Java, but scheme isn't immune. I object to hygienic macros as not worth the layers of abstraction they create. Things like racket's modules imposing an order on declarations and scheme's phase-separation rules, these I'm willing to accept for performance reasons. But they often get rationalized as good things independent of implementation considerations, which forgets the original lessons of Lisp, IMO.

Shriram Krishnamurthi

unread,
Nov 13, 2013, 5:35:28 AM11/13/13
to pyret-...@googlegroups.com
Again, this is where having a design focus helps. My focus is on those
learning to program. Learning to program is hard enough without
imposing even more rules.

Here's the thing. There's no such thing as "a" programming language.
Even one language has numerous sub-languages inside of it: the
languages of expressions, definitions, types, argument lists, etc.,
etc. Keeping the number of languages small and manageable inside one
language is therefore very important. (I'm fond of the opposite
direction too -- my dissertation went to the other extreme -- but not
in this setting.) It is also an argument for deferring types for a
little while: they're already learning 2-3 languages from the start,
so adding a fourth language -- with its own syntax, grammar,
well-formedness rules, and interaction with the other languages -- is
perhaps best after they've first gotten some facility with the others.

The other issue is error reporting: to be able to generate not only
simple errors but also have them be decipherable *and* actionable.
Saying "add spaces around binops" is easy to learn, recognize, and
implement. Learning more complicated rules is certainly possible, and
may even be easy, but every distraction takes time to recover from,
and the more mental energy a person needs to expend to recover
potentially has consequences for how long it takes to get the overall
task accomplished.

Of course, having said all this about "beginners", I don't think
things are that different for experienced programmers, either.

Therefore, I'm convinced that there is virtually no payoff in trying
the kind of syntax experiment you suggest. And this hopefully helps
people understand the kinds of design principles that drive the growth
of Pyret.

Separately, I think you may also suffer from excessive respect for our
Lisp antecedents. There's a reason we gave this paper the subtitle we
did:

http://cs.brown.edu/~sk/Publications/Papers/Published/ffkf-mred/

It's to say we are aware of what Lispers were trying to accomplish,
but we also believe these things should be done in certain ways (e.g.,
that respect abstraction boundaries).

Shriram

Kartik Agaram

unread,
Nov 13, 2013, 1:11:06 PM11/13/13
to pyret-...@googlegroups.com
Happy to concede that my infix might prove a burden while learning programming.

> Separately, I think you may also suffer from excessive respect for our Lisp antecedents.

Ha, first time I've been accused of that! I'll be back on this after I read that paper.

> ..these things should be done in certain ways.. that respect abstraction boundaries.

That seems the crux of our disagreement: I've gradually grown hostile to abstraction. Abstraction too inevitably leads to specialization, with people learning either to use an interface or maintain its underpinnings. This specialization is bad: http://akkartik.name/post/libraries2.

Many abstractions only seem useful in a local view, but when you look globally the aggregate mass of abstractions doesn't pay for itself. Unfortunately, our language and rhetoric almost exclusively emphasizes local considerations, making us blind to global costs: http://akkartik.name/post/readable-bad.

I'd like to live in a world where using an interface over time encourages one to gradually understand its internals, thus replacing vicious cycles of over-abstraction with virtuous cycles of full-stack understanding: http://akkartik.name/about.

(All these ideas are in great flux; I love listening to feedback on them. I'm not quite as attached to my lisp.)

Shriram Krishnamurthi

unread,
Nov 13, 2013, 2:14:44 PM11/13/13
to pyret-...@googlegroups.com
I'm not unsympathetic; I have complicated views on abstraction.
However, this is the _pyret_ list, and Pyret has decided that it is
not opposed to abstraction, and that's not going to change. So I'd
suggest this isn't the forum to be debating or discussing these
points.

Shriram

Kartik Agaram

unread,
Nov 13, 2013, 4:56:15 PM11/13/13
to pyret-...@googlegroups.com
Sorry, I wasn't suggesting pyret should switch to my infix, be more like lisp, or care less about abstraction. I shared an alternative design at a local optimum some energy barrier away. Then I followed the conversation where it led, noting that nobody dropped the list in a response. It wasn't apparent precisely where the 'on topic' line is here.

Shriram Krishnamurthi

unread,
Nov 13, 2013, 11:45:28 PM11/13/13
to pyret-...@googlegroups.com
Sorry, didn't mean to step on your toes. This used to be a public list
with only private members, but we decided there was no harm in
throwing open the development process. I also appreciate there are
lots of interesting questions here, and want to be open to them. The
challenge is to figure out how to do that while keeping it somewhat
narrowly focused to its specific purpose at the same time.

Thanks,
Shriram

Kartik Agaram

unread,
Nov 13, 2013, 11:53:13 PM11/13/13
to pyret-...@googlegroups.com
Makes sense. Apologies as well.

Daniel Patterson

unread,
Nov 14, 2013, 4:27:50 PM11/14/13
to Shriram Krishnamurthi, pyret-...@googlegroups.com

Perhaps we should create a separate pyret-devel list (not private)? The
name of this one makes it seem less focused than it is (or at least,
was).
Reply all
Reply to author
Forward
0 new messages