bakpakin / Fennel

Lua Lisp Language
https://fennel-lang.org
MIT License
2.44k stars 126 forks source link

tutorial: what characters can be used when naming things? #314

Closed uvtc closed 4 years ago

uvtc commented 4 years ago

Somewhere near the beginning of the tutorial it should mention what characters can be used when naming things (such as functions, variables, etc.). That is, it's a surprise later when you see things can be named with a question mark in them. Can you use exclamation marks too? (Hm, why would you?) How about a trailing single-quote-mark (prime)? Any reason to use an underscore (maybe for let bindings that you aren't concerned with ... maybe this can be mentioned later when destructuring is explained).

Also maybe an indented note about naming conventions in Fennel would be helpful?

technomancy commented 4 years ago

Great point! This would be a good addition to the tutorial; we should add it.

uvtc commented 4 years ago

Ok, will do, but could you first please tell me:

technomancy commented 4 years ago

Ok, will do, but could you first please tell me:

Sorry; didn't mean to say that you should be the one to do it. But if you want to, I won't object. =)

  • can you use ! in a name, and is there a reason to? (I think some langs may use this to indicate mutation, but I don't think Lua nor Fennel does...)

It's a legal character, yes. It's often used to indicate side-effects, but it's not a convention to always use it for anything side-effecting.

  • can you use single quote as a prime, and should it even be suggested? (as opposed to just coming up with another name, rather than old-name')

This is currently not supported; quote and backquote are treated as form-level quoting even if it's at the middle or end of a symbol.

I think we could look into changing this, but that's how it currently works.

  • is an underscore typically used when you don't care about the value, as in (let [[foo _ bar] some-arr] ...)?

Yep!

  • is an underscore used in some other way? For example, some langs use them to indicate private functions, or functions that are not expected to be called outside of a given module.

No, it is just the unused binding.

  • It looks like you can start an identifier with a question mark (for example, in the section on function arity and lambda). That looks unusual to me. What is the convention for prepending a ? vs appending one?

This is maybe the only Fennel-specific rule here; starting an identifier with a question mark indicates that it might be nil. In the context of lambda and match this is enforced by the compiler, but in other contexts it can be used as a convention to convey intent even without enforcement.

The code that defines valid symbol characters is here:

(fn issymbolchar [b]
  (and (> b 32)
       (not (. delims b))
       (not= b 127) ; backspace
       (not= b 34) ; backslash
       (not= b 39) ; single quote
       (not= b 126) ; tilde
       (not= b 59) ; semicolon
       (not= b 44) ; comma
       (not= b 64) ; at
       (not= b 96))) ; backtick

So for a character to be used it must:

Anything else is fair game!

If you want to submit a patch to the tutorial explaining the rules that'd be great! If not I can do it later at some point.

Benaiah commented 4 years ago

Just a note that there is another language-level use of underscore, though it's not in symbol names. It can be used to space out numbers, like 100_000_000, which compiles to 100000000. This is documented here: https://fennel-lang.org/tutorial#numbers-and-strings

uvtc commented 4 years ago

This doesn't look right to me:

This is maybe the only Fennel-specific rule here; starting an identifier with a question mark indicates that it might be nil. In the context of lambda and match this is enforced by the compiler, but in other contexts it can be used as a convention to convey intent even without enforcement.

The leading question mark looks more like an operator, and doesn't look like it should be part of the identifier. That is, instead of:

(lambda print-calculation [x ?y z] (print (- x (* (or ?y 1) z))))

I'd think that should be:

(lambda print-calculation [x ?y z] (print (- x (* (or y 1) z))))

I think it would be a mistake to let identifiers start with anything other than a letter or underscore.

uvtc commented 4 years ago

Took a try at it (see #315).

I see that names can start with a dash too, but maybe that looks a little too strange (ex. (var -a 10) where -a looks a lot like "negative a" :) ) to use without causing confusion. Well, at least maybe not worth mentioning in the tutorial.

technomancy commented 4 years ago

I think it would be a mistake to let identifiers start with anything other than a letter or underscore.

Oh, it's much too late to make a change like that. Anyway lisps tend to do away with arbitrary limitations on the character constituents of identifiers that other languages have. Allowing question marks at the end but not at the beginning would be odd; the only reason it works that way for digits is an implementation detail of the parser; it's not great.

uvtc commented 4 years ago

Oh, it's much too late to make a change like that.

Oh boy. Ok, better make sure my seat belt's on. :)