Crystal immutability

394 views
Skip to first unread message

Hristo Kochev

unread,
Jun 26, 2016, 3:23:00 AM6/26/16
to Crystal
Hello,

I would wonder what is community thinking towards immutability compile flags or at least have Object#freeze lke Ruby?

Ary Borenszweig

unread,
Jun 27, 2016, 10:18:23 AM6/27/16
to crysta...@googlegroups.com
Hi,

We do like some immutability when it's applicable and efficient.

Strings are immutable in Crystal so there's no need to use freeze with them. If you need an immutable array you can use tuples instead (most freeze cases I see in Ruby is for constants, FOO = [1, 2, 3].freeze, in Crystal you'd use a tuple).

Other immutable types can be built from other types, for example the record macro creates an immutable struct with some fields.

Doing something like `Object#freeze` would be overkill for Crystal, as every instance variable access would need to check this "freeze" flag, disallowing many optimizations and making everything very slow.

Instead, one should define immutable objects as needed.



On Sun, Jun 26, 2016 at 4:23 AM, Hristo Kochev <h.l.k...@gmail.com> wrote:
Hello,

I would wonder what is community thinking towards immutability compile flags or at least have Object#freeze lke Ruby?

--
You received this message because you are subscribed to the Google Groups "Crystal" group.
To unsubscribe from this group and stop receiving emails from it, send an email to crystal-lang...@googlegroups.com.
To post to this group, send email to crysta...@googlegroups.com.
Visit this group at https://groups.google.com/group/crystal-lang.
To view this discussion on the web visit https://groups.google.com/d/msgid/crystal-lang/30b2f553-6a76-4ea1-b263-cbd0cfe7e519%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Ary Borenszweig         Manas Technology Solutions
[ar.phone]                      5258.5240       #ARY(279)
[us.phone]                      312.612.1050    #ARY(279)
[email]                         aboren...@manas.com.ar
[web]                           www.manas.com.ar

Hristo Kochev

unread,
Jun 27, 2016, 11:24:56 AM6/27/16
to crysta...@googlegroups.com
Hello Ary,

Thank you for record macro reference.
Is this mean that all immutable data is passed by value and would that allow deeply recursive methods to be consturcted?  


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

To post to this group, send email to crysta...@googlegroups.com.
Visit this group at https://groups.google.com/group/crystal-lang.

For more options, visit https://groups.google.com/d/optout.



--
Regards,
kochev

Ary Borenszweig

unread,
Jun 27, 2016, 12:48:42 PM6/27/16
to crysta...@googlegroups.com
You can create a class and don't provide methods to mutate its instance variables.

With deeply recursive methods you mean doing tail call optimization? If so, I believe that's more appropriate for functional languages (and Crystal is not such language), and there's also this: https://pragtob.wordpress.com/2016/06/16/tail-call-optimization-in-elixir-erlang-not-as-efficient-and-important-as-you-probably-think/


For more options, visit https://groups.google.com/d/optout.

Hristo Kochev

unread,
Jun 27, 2016, 2:07:08 PM6/27/16
to Crystal
Great Ary,
 wou
Thank you once again and for your work on crystal. I was just wondering how the community around the Crystal see it's future?
In which directions we could push the language and it's ecosystem?   

Mike Perham

unread,
Jun 27, 2016, 4:37:32 PM6/27/16
to Crystal
Crystal needs:

1. Evangelists: tell your friends how good it is, publish blog posts, etc.
2. Shards to integrate with other APIs, systems, tools.

Mike

Hristo Kochev

unread,
Jun 28, 2016, 10:11:55 AM6/28/16
to Crystal
Thanks Mike,

That is true in general for any young language :), but my point was to initiate some discussion about how community see the feature of this wonderful language.

Hristo 

Luca Ongaro

unread,
Jun 28, 2016, 2:56:04 PM6/28/16
to Crystal
Adding to the discussion about immutability, although Crystal does not enforce strict immutability (a good decision, in my opinion) it provides all the facilities to implement efficient immutable data structures. I recently authored a shard providing immutable maps and vectors with structural sharing:

https://github.com/lucaong/immutable

Hristo Kochev

unread,
Jun 28, 2016, 3:32:22 PM6/28/16
to crysta...@googlegroups.com
Great work Luca, thanks ...


On Tue, Jun 28, 2016 at 9:56 PM, Luca Ongaro <lukeo...@gmail.com> wrote:
Adding to the discussion about immutability, although Crystal does not enforce strict immutability (a good decision, in my opinion) it provides all the facilities to implement efficient immutable data structures. I recently authored a shard providing immutable maps and vectors with structural sharing:

https://github.com/lucaong/immutable
--
You received this message because you are subscribed to a topic in the Google Groups "Crystal" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/crystal-lang/_GCDcmHvEck/unsubscribe.
To unsubscribe from this group and all its topics, send an email to crystal-lang...@googlegroups.com.
To post to this group, send email to crysta...@googlegroups.com.
Visit this group at https://groups.google.com/group/crystal-lang.

For more options, visit https://groups.google.com/d/optout.



--
Regards,
kochev

Joseph Method

unread,
Jun 29, 2016, 11:22:55 AM6/29/16
to Crystal
This might be overkill, because as people say you can just write immutable code, but one thought I had was that you could have a magic comment similar to the Ruby frozen_string_literals comment, which you could use to assert at compile time that a file only uses immutable objects and data structures. Now how you would actually do that I don't know. This could actually be done as a project separate from the main crystal project though.

Hristo Kochev

unread,
Jun 29, 2016, 1:44:33 PM6/29/16
to crysta...@googlegroups.com
Joseph, that was my way of thinking too ...


For more options, visit https://groups.google.com/d/optout.



--
Regards,
kochev

Luca Ongaro

unread,
Jun 29, 2016, 1:59:46 PM6/29/16
to crysta...@googlegroups.com

While a tool that asserts that certain classes have no setters is very easy to implement, ensuring full immutability would be very hard as far as I see. One would have to assert that no method apart from the constructor writes any state, and no mutable object is exposed. This while still allowing for memoization, returning defensive copies of mutable objects, and other forms of "allowed" mutability.

Other languages enforce immutability from the ground up by having everything immutable apart from a few well defined mechanisms (e.g. Clojure). But doing this in Crystal would mean creating a totally different language. While being a big fan of functional programming and immutability, I personally think that it's an advantage for Crystal to let the programmer decide. It enables use cases like game programming where in-place mutability is desirable.

One thing that I personally think would be nice in a future is to have solid implementations of fundamental immutable data structures in the core (immutable map, vector, set, etc.). They would come very handy when doing concurrent programming.


Jérôme Gravel-Niquet

unread,
Jun 29, 2016, 4:00:57 PM6/29/16
to crysta...@googlegroups.com
I thought Structs were supposed to be immutable due to how they were allocated.

I don't know if it's enforced though.
You received this message because you are subscribed to the Google Groups "Crystal" group.
To unsubscribe from this group and stop receiving emails from it, send an email to crystal-lang...@googlegroups.com.

To post to this group, send email to crysta...@googlegroups.com.
Visit this group at https://groups.google.com/group/crystal-lang.

Hristo Kochev

unread,
Jun 30, 2016, 3:43:34 AM6/30/16
to crysta...@googlegroups.com

Nope theu are not, but recirds are ...please read Ary ansewer on that

Joseph Method

unread,
Jun 30, 2016, 10:25:29 AM6/30/16
to crysta...@googlegroups.com
I agree that it would be difficult to guarantee immutability. What I'm thinking is that it could be an incremental approach to guarantee "more" immutability. One naive approach would be a linter that would operate against a whitelist of standard library classes, and you would have to add your own classes to the whitelist. Also it seems like you would get a long way by just asserting that instance variables can't be changed outside of the initializer but then it would prevent those cases you mention. One thing you could do is explicitly allow the blocks where the allowed mutability happens, like with Rubocop when you want to make an exception.

I'm personally not very invested in functional programming. I don't do any of it myself (yet). My thought is that you either have a completely conventional approach, where you just commit to writing in a functional way, or you can have a tool that is layered on, but there's no way that Crystal itself becomes an immutable language. What you could have is a set of core classes and libraries that are validated in some way as being immutable, so that if you only use those you have a reasonable guarantee of having a thread-safe program. The reason I'm emphasizing a tool or whitelist is that it's hard otherwise to know if libraries and their dependencies use immutable data structures.


For more options, visit https://groups.google.com/d/optout.
--

- Joseph Method

Brian J. Cardiff

unread,
Jun 30, 2016, 10:42:24 AM6/30/16
to crysta...@googlegroups.com
Regarding how structs work:

1. They are allocated in the stack and passed by value
2. Their state can be mutated, but the change will not be visible to the caller. And can only be performed from it self.

for example with

struct WrappedInt
  def initialize(@v : Int32)
  end
  
  def inc
    @v = @v + 1
  end
end

def call_inc(x)
  x.inc
  x
end

a = WrappedInt.new(1)   # =>  WrappedInt(@v=1)
a.inc
a                                      # =>  WrappedInt(@v=2)
call_inc                            # =>  WrappedInt(@v=3)
a                                      # =>  WrappedInt(@v=2)

Due to pass by value the `a` is not changed, but a copy is changed in `call_inc` and a mutated copy is returned.
If a struct has a reference, the reference is copy in a pass by value but there will be aliasing for sure.



You received this message because you are subscribed to the Google Groups "Crystal" group.
To unsubscribe from this group and stop receiving emails from it, send an email to crystal-lang...@googlegroups.com.

To post to this group, send email to crysta...@googlegroups.com.
Visit this group at https://groups.google.com/group/crystal-lang.

For more options, visit https://groups.google.com/d/optout.
--
Brian J. Cardiff - Manas Technology Solutions
[ar.phone] 4796.0232 #BCR(227)
[us.phone] 312.612.1050  #BCR(227)
[email] bcar...@manas.com.ar
[web] www.manas.com.ar
[weblog] http://weblogs.manas.com.ar/bcardiff/

tabcom...@gmail.com

unread,
Sep 24, 2016, 3:03:24 PM9/24/16
to Crystal


On Thursday, June 30, 2016 at 10:42:24 AM UTC-4, bcardiff wrote:
Regarding how structs work:

1. They are allocated in the stack and passed by value

Pass by COW, would be more efficient.
Reply all
Reply to author
Forward
0 new messages