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

[RFC] Immutable methods #1518

Closed
technorama opened this issue Sep 18, 2015 · 6 comments
Closed

[RFC] Immutable methods #1518

technorama opened this issue Sep 18, 2015 · 6 comments

Comments

@technorama
Copy link
Contributor

A method may modify any data structure (almost) anywhere in the program. Having a way to declare that a method is side effect free would aid in concurrent programming.

A new keyword fun could be used in place of def to indicate the method is immutable.

Benefits:

  • Fewer errors in concurrent programs.
  • Easier to find data modification errors by reducing the search space to mutable methods.
  • Documentation could reflect immutability.
  • Classes could be automatically flagged as immutable if all methods are immutable.
  • The compiler can make additional optimizations based on immutability.

Examples of immutable methods:

fun foo
  true
end

fun foo
  Bar.new @bar
end

Any of the methods below would result in a compile time error:

fun foo
  @bar = true
end

fun foo
  set_bar 
end

def foo
  @array << 1
end
@jhass
Copy link
Member

jhass commented Sep 18, 2015

Note that fun is already used to generate named functions that aren't name mangled, as well as for C bindings.

I don't think we should introduce without also having a direct benefit from a compiler feature this would allows us to implement.

@technorama
Copy link
Contributor Author

The main feature is being able to reason about what code modifies state. There doesn't have to be a compelling compiler feature (but there are). Lots of people are asking for immutability (#1512, #263, #65), not just in crystal but many programming languages.

fun provides a way to add immutability incrementally. If you'd prefer a class based approach that's acceptable also but we should add it sooner rather than later as undoing code that relies on mutable data structures is hard to untangle.

fun can also require that all methods called are also immutable regardless of the receiver of the method. I don't think a class based approach would normally allow for such stringent validations.

I wasn't aware that fun was used outside of lib. Possibly change the current fun to an extern prefix? Or use another identifier instead of fun. I'd prefer the keyword for immutability be fun based on existing FP usage of the keyword. If that doesn't work there are wordier options immutable def foo
immutable class Foo

@js-ojus
Copy link
Contributor

js-ojus commented Sep 19, 2015

@technorama : If Crystal were to consider this, I would much prefer effect types. See Koka's approach for an interesting take. Look at Nim's for another.

A way to phrase what I am saying is: a method takes a tuple of data (of size zero or higher) as its input, answers a tuple of data (of size zero or higher) as its output, and optionally specifies a union type of effects that it can cause.

About a year-and-a-half ago, I wrote my thoughts as of then.

As Erik Meijer says, there is only one way to be pure, but potentially infinite ways to be impure. Haskell takes this approach.

@dimparf
Copy link

dimparf commented Sep 21, 2015

This is analogous to the word pure in D lang end others.
Functions (methods) without side effects.

@ozra
Copy link
Contributor

ozra commented Sep 23, 2015

I'd really like to see this too.

Preferably I'd like all parameters to be immutable by default, and then mark mutable params with some annotation, like mut or whatever. This way methods would be flagged pure if no params are marked mutable, and classes marked pure if no methods have mutable params. Instead of using another keyword for func declaration and going the mark-the-whole-function route.

Otherwise, marking parameters as immutable, but default to mutable, if the other option is way out of line for Crystal.

I'd also like to be able to annotate variables as immutable (set once), and I think I've already issued both these things before, so sorry if it's repeat in this comment.

@asterite
Copy link
Member

I'm closing this. A concrete algorithm is needed for this to work, for example how to detect that a function is indeed immutable/pure. But, again, this adds more syntax and semantic to the language and everyone will have to learn it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants