Keeping the syntax and the need to memorise syntax simple

Hello. I’m new to Julia and am glad y’all have created such a programming language. However, when learning the syntax, I had the same problem as mentioned here.

Programming is a bit less stressful when certain symbols are easy to type, when the code is easy to read and when lesser nuances of the syntax need to be remembered. It’s like UI/UX for software syntax.

Some examples:

  • In rand(Int, 2) etc, it would be easier to type int, float etc, if we could just type it without having to press the Shift key. Also, it looks neater when they are lowercase.

  • Why is there an exclamation mark for pop !(Array1)? Why not just pop(Array1)? The exclamation mark is what we are familiar with as a not operator. It’s very confusing to see it in a function name.

  • I used to absolutely hate the -> operator in C++. It was so annoying to have to reach out for those two characters on the keyboard when it would have been so much simpler to access a period “.”. Moreover, using abc.hello() looks so much neater than abc->hello(). In Julia I see the same problem with syntax like Dict3=Dict{String, Integer}("a"=>10, "c"=> 20). Could you please substitute => with : and for specifying the typing, dict<string, int> is so much more accessible on the keyboard, easier to type, readable and looks so much better.

  • Case usage of functions like SubString() could perhaps be substring() or subString().

There are many other aspects of Julia syntax that are well designed and I liked a lot. I hope y’all would be open to considering changing Julia’s syntax to make it easier to type and read, and to make it more intuitive. It’d also be nice to have a simple way to install and use Julia (especially in IDE’s we are already familiar with: Netbeans, Eclipse etc.). I went through a bit of a struggle the last time I tried installing it and using it via Atom.

Most of the things you mentioned are matters of taste; I for once find the syntax generally well-designed and easy on the eye. But I want to answer your question regarding pop!():

The “!”, by convention, indicates that pop!() operates in-place, meaning that it modifies its input argument(s). This is less obvious with a function with a name already suggesting this (like pop!()), but keep in mind that there functions that come in both varieties (with and without “!”), e.g.map() and map!(). Knowing that a function operates in-place is important as they can create hard-to-spot bugs in your code if applied unknowingly. I know that some style guidelines for languages suggest that you express this semantically (like pop() and popped()) but I find ! much clearer.

18 Likes

Thank you for explaining it, Marc. Yes, I see it is useful to have an indication for an in-place operation. But the syntax changes are not a matter of preference. It’s about the ease of reaching keys on the keyboard, the intuitiveness of syntax and even the general uniformity of look and clutter. Very similar to how you’d decide colours and widget placement in UI/UX design. An interaction designer should suggest such changes to syntax. Engineers are usually not trained on these aspects of usability. For example, since pop!() would confuse people, how about a syntax like this pop(()) to indicate an in-place operation? I know it’s not the best suggestion (I’m an engineer too :slight_smile: ), but making syntax intuitive and easy to type and remember can make a programming language a lot more appealing and easy to use. I’d like Julia to gain a lot more traction in the AI field.

By convention, types are CamelCase and functions & variables lowercase, analogue to e.g. Python.
rand(Int, 2) is referring to the Int type, therefore it is written in CamelCase.

I actually like the ! convention for in-place functions, it is very simple and clear. E.g. in Python (Pandas) sometimes keyword arguments are used (inplace=True), which is much more verbose.

Regarding the definition of pairs with => I agree that it is sub-optimal. There is a reason why : cannot be used, but I do not remember it anymore (was it due to the ternary operator?).

6 Likes

What is intuitive is also very subjective. Using exclamation points ! for indicating mutation is very common in Ruby and some Lisps. They also use question marks to indicate predicates (which I sometimes miss), e.g. Julia’s isempty can in Ruby and some Lisps be written as empty?.

pop(()) would be very confusing, since it corresponds to applying the function pop on an empty tuple ().

12 Likes

Julia is not at the stage of development where changes like this are made. The language has been fully developed, stable and non-breaking for two years since the 1.0 version was released. Even then, disruptive changes like this would not have been considered without very strong cause. For these kinds of changes to be plausible, you would have had to have suggested them some five years ago or more.

Julia uses the quite common convention that types are capitalized. This helps people reading code understand what is happening—which names are types and which are not.

Why is there an exclamation mark for pop !(Array1) ? Why not just pop(Array1) ? The exclamation mark is what we are familiar with as a not operator.

As explained above, Julia uses the convention that function names ending with ! mutate one of their arguments. This convention has been extremely successful and is certainly not something we would consider changing. Like the capitalization convention, it helps people reading code understand what is happening. If a function modifies an argument, it’s quite important that one be aware of that both when writing and reading the code. Also, mutating functions are somewhat dangerous, so it makes sense that they be somewhat harder to type.

Could you please substitute => with : and for specifying the typing, dict<string, int> is so much more accessible on the keyboard, easier to type, readable and looks so much better.

The a:b syntax is already used to construct range objects, so it is not available.

Case usage of functions like SubString() could perhaps be substring() or subString() .

Again, SubString is a type so it is capitalized.

A lot of these requests seem to have to do with wanting to avoid using the shift key, which would really massively reduce the amount of valuable ASCII real estate available (cutting it fully in half). Moreover, they seem to focus on minimizing the effort of typing code, whereas the conventions are designed to help people read and understand code. Since code is written once but read many times, it is far more important to optimize a language to be easily understood than to make it as easy to type as possible. Knowing at a glance which names are types and which functions mutate things are both useful and important. Much more important than avoiding hitting the shift key sometimes.

48 Likes

Ok, if the language is already beyond the point of changing these, there’s no point discussing it any further. Thank you all for giving it fair consideration.

7 Likes

Thanks for the feedback! I hope you enjoy using Julia despite the shifting :grinning:

18 Likes

Note that you and I do not have the same keyboard layouts, and neither do people in many other countries either. Most commonly used keys are awkward to reach on a swedish keyboard.

5 Likes

Not only on Swedish… I hope that makes you feel better. :slightly_smiling_face:

Welcome to the club! Luckily for you, Julia doesn’t have such issues. I want to clarify some things:

You don’t need to always specify types (hello, C++). String, Int64 will be automatically deduced by compiler:

julia> Dict("a" => 10, "c" => 20)
Dict{String,Int64} with 2 entries:
  "c" => 20
  "a" => 10

You don’t like =>? You can replace it with any other available symbol (from How to change => to another symbol?):

julia> const → = =>
Pair

julia> 1 → 2
1 => 2

Regarding this:

Types are generally written in UpperCamelCase, as they are in Julia base / standard library. It’s standard in every modern language to write object type names that way, and base types are in no way more special than any object type you declare in Julia.

That may not satisfy your needs, though. Do you really dislike pressing Shift key? The solution is simple:

julia> const int = Int
Int64

julia> const float = Float64
Float64

julia> int(1.0)
1

julia> float(1.0)
1.0
7 Likes

float is an already defined function, that transforms an integer type to an equivalent float type,of variable size, for example:

typeof(float(BigInt(2))) #bigfloat
7 Likes

Good catch! But the good thing is there are plenty good names still available for @Nav, such as float64.

2 Likes

Or maybe double (Julia actually already defines the alias Cdouble, but I assume that capital C won’t be appreciated much)

3 Likes

You guys are really cool! Changing an operator to another symbol is something I didn’t expect. Nice…as long as I could change it to a colon. Anyway, my focus was not on having to use the Shift key. I know there are conventions and I know how they are useful because programmers maintain code 90% of the time. Debates about convention and readability have stretched on for long. If I could summarize what I was putting forward, it was about being able to type code in a flow without having to reach for any unnecessary keys and to avoid a jagged/uneven appearance in syntax as much as possible. Your suggestions of const float=Float64 are excellent solutions to the problem. Anyway, I feel these issues are going to become irrelevant very soon, because the GPT-3 demonstrations show that in the near future, any IDE with a GPT plugin would be able to auto-generate a lot of boiler-plate code without us having to actually type the entire line.

1 Like

Incidentally, please make a post explaning this in general. I keep repeating explanations like this, and it would be helpful to just link something polite but reasonably authoritative from the core devs when suggestions like this come up.

8 Likes

In addition to the considerations that others have made, putting code into the right case is the perfect job for IDEs auto-completion, if you really want to avoid pressing shift.

5 Likes

Well-designed Julia code often doesn’t have much boilerplate, especially the top-level code you write during interactive work. Generic functions, type inference and duck typing means you often don’t need to put type annotations in your code. Type assertions on variables are hardly ever used.

@anon37204545’s example is illustrative

Constructing arrays can be done without types:

julia> [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> [1.1, 2.2, 3.3]
3-element Array{Float64,1}:
 1.1
 2.2
 3.3

and this generalizes to all types, even user-defined types.

In the cases where you do need to write them out, I think they should stick out.

5 Likes

I can’t stress this enough. I see from time to time comments like this where people suggests changes to languages (not just Julia) to make typing easier: that should be the job of an IDE, not of the language.

10 Likes

Given the number of programming languages a person has to learn to stay relevant in the industry, it brings a bit of what I’d call “syntax fatigue”. Each time I use a new language, I don’t want to have to figure out what characters are used for commenting out lines, what the syntax for a for loop is etc. It’d have been nice if there would be some universal template which could be decided for conventional programming paradigms at least. The newer concepts could have their own special syntax…no issues. And yes, it’d be great if the IDE could take care of most of the headaches.
I agree with Tamas about the creation of a page where the design decisions of Julia are explained. Notion did this during their design phase.

Build institutional knowledge as you go: Given Notion’s early history, Ivan and Simon have special appreciation for institutional memory — what has been tried before, what worked and what didn’t. As far as they’re concerned, nothing should ever be deleted. “I am constantly like, ‘Do not replace that text! Just copy and create a new canvas!’” says Ivan. “In Figma, you open any file of ours and there’s seven or eight canvases all side by side. You see how the words and design evolved between one and the next.”. With that kind of record, people can learn from the mistakes of those who came before them. Notion’s Figma workspace is divided into a granular folder tree structure that makes it simple to navigate to any past project.

1 Like

Sincerely, the only way I see to address the underlying issue (this is Keeping the syntax and the need to memorise syntax simple) in a way that is yet viable to Julia 2.0, and that would, sincerely, solve the largest problem I have with Julia syntax, is to just have a version of each function of the standard library with underscores between every word, so I do not have to remember if it has or not underscores.

Obviously, this also can be done by a package, and if nobody will, someday I will implement this package. It is just a little more than what I believe I would be able to maintain right now.

6 Likes