PSA: New keywords for defining types

In a rather disruptive, but I think worthwhile, change, we now have different keywords for defining types. Here’s a quick summary:

  • immutable changes to struct
  • type changes to mutable struct
  • abstract changes to abstract type ... end
  • bitstype 32 Char changes to primitive type Char 32 end

The PR that did this: https://github.com/JuliaLang/julia/pull/20418
Kristoffer has a helpful script for the struct part of the change here: https://github.com/JuliaLang/julia/pull/20418#issuecomment-277201589
Hopefully it can be extended to handle abstract and primitive as well.

For now, type and immutable are still allowed without a deprecation warning, since Compat.jl won’t be able to support the new syntax.

Using type ... end allows Compat to support the new abstract & primitive type syntax, and also allows us future flexibility to add things inside such definitions. The extra verbosity is considered tolerable since these keywords are used much less often than the struct keywords. It also means that in 1.0, the words abstract, type, immutable, mutable, and primitive will be usable as normal identifiers. The only type-related word that will actually be reserved is struct.

This change allows us to use clearer terminology, where keywords correspond to descriptive terms where applicable:

primitive type: a scalar-like type that’s just a series of bits, no fields
struct: data consisting of named fields
(im)mutable type: a type that can or can’t be mutated
bits type: pointer-free, immutable data (might be either struct or primitive)
type: something that describes a class of values

The preferred default user-defined type is struct. No more telling people to go through and make everything immutable for performance :slight_smile:

-Jeff

22 Likes

Can we have such a script that corrects all the Julia material out there on the web? :slight_smile:

1 Like

With the changes this will do to the parser, does this mean one can define macros like

@inherits interface type
  # does stuff
end

or will only specific `keyword type` phrases parse correctly?

Can you please elaborate on this? Does this mean that the change is not merely syntactic, but the semantics also changed, and struct is now faster than it used to be?

This should parse on old julia versions too.

It’s just that the easiest and most obvious thing to use used to be type. That’s now referred to as a mutable struct. If you don’t need mutable behaviors, though, you really should have been using immutable. That’s now just struct.

Now it’s most likely that folks will use struct first, and only use mutable when they actually need a mutable structure.

8 Likes

I think immutable and mutable would have been
much better choices than struct and mutable struct.

Single word keywords and only a single change typemutable.

@ChrisRackauckas Only specific word type keywords will have this parsing.

@turtle Yes that would have been a slight improvement over what we had before, but we would then still lack a descriptive noun for this kind of type. primitive types and tuples are also immutable, so it would still be a bit unclear. It’s also a bonus to avoid stealing the words abstract and primitive.

Naturally it is really hard to form an unbiased opinion on such a change after months of getting used to the current syntax. What I can say is that I am glad these kind of changes are done sooner rather than later though. Thanks to everyone putting so much thought into these aspects

13 Likes

I don’t like suggesting this without volunteering code, but would it make sense to take this opportunity to fix the singleton inconsistency?

type X end
X() === X()  # true

That would be a rather unrelated semantic change; this was just a renaming.

Whether this is inconsistent is debatable. There is no way to tell X() and X() apart aside from === itself, so === giving either true or false is equally consistent with the rest of the language.

That’s also true of a mutable type with a single ::Void field, but its instances are !==

Given that, what’s the rationale for using function as a keyword rather than method?

Yes, you’re right. We could extend the current behavior to any struct whose size is 0. Either that or always making distinguishable instances, as you suggest, would be defensible.

It’s subjective, but I feel this is not so much of a problem. It might be because methods are not really first class. Typical code doesn’t directly manipulate methods, so that confusion doesn’t come up. The function keyword is great when a function has one definition. But many people are also used to the idea that a function can have multiple definitions, as in C++, so using the same syntax for each definition is not so bad either.

2 Likes

Wouldn’t “value type’” be a more standard name for “bits type”? Meaning also a type that is allocated on the stack rather than the heap. At least that’s the terminology that’s used wen discussing such things in Scala, C# (structs) or Java 10.

No, because struct (formerly immutable) is also a value type and can also be stack-allocated. (And these types may not go on the stack, either—the compiler may put them in registers.) Also, I’m skeptical of naming types based on implementation details. Especially since compiler optimizations may be implemented in the future to stack-allocate other kinds of objects (e.g. https://github.com/JuliaLang/julia/pull/12205).

3 Likes

yes but int he definition that Jeff gave that I quoted bits type is both primitive types & struct. So if you say no because struct is also a value type you just confirmed my point.

“bits type” also means that the object does not contain any pointers. That’s orthogonal to how it is allocated or how it is passed. It means, for example, that you can copy the object into a shared memory segment and have things work.

OK, so the noun type is replaced by the noun struct for composite types.

I would still prefer less typing.
As far as I remember immutable was just an abbreviation for immutable type.
Would it be an option to use mutable as an abbreviation for mutable struct ?

type is replaced by mutable struct, to be exact.

Semantically - yes, but syntactically immutable type is invalid, at least in Julia 0.5.