<CraigBuchek>
I was wondering if it might make sense for a language to not allow reassignment.
<CraigBuchek>
Was also just reading about Swift var versus let.
<asterite>
But then all variables would be immutable
<CraigBuchek>
And wondering if we even need var.
<CraigBuchek>
Yes.
<CraigBuchek>
:)
<asterite>
I never understood what's the benefit of saying that a variable is immutable
<asterite>
If you need to re-assign it, you remove the "immutable" modifier
<CraigBuchek>
Think of them as scoped constants then.
<asterite>
If you never re-assign it, you can put "immutable" for documentation purposes
<asterite>
But it doesn't give any performance boost
<asterite>
A scoped constant: a = 1
<CraigBuchek>
I was thinking more in terms of compiler complexity.
<asterite>
where you never re-assign "a"
<asterite>
LLVM optimizes it away
<asterite>
Mmm… you need to add the concept of immutable variables, the user has to type more, and the compiler has to check that you don't assign to an immutable variable
<CraigBuchek>
Especially the complexity of the type inference.
<asterite>
It seems like a lot more work to do
<asterite>
Ah, I see what you mean
<CraigBuchek>
No, I meant making *all* variables immutable.
<asterite>
Yes, it would make it just a little faster, I think, saying immutable a = 1
<CraigBuchek>
(Of course, then "variable" would be the wrong term.)
<asterite>
Ah, no… it would be the same, in fact
<CraigBuchek>
So I'm asking about the cost/benefit of *allowing* variables to be reassigned.
<CraigBuchek>
I don't see much benefit in allowing it.
<asterite>
Did you program in Erlang?
<CraigBuchek>
But the cost might not be all that high, as far as extra code/complexity in the compiler.
<CraigBuchek>
I'm also wondering if there's a cost or benefit in terms of the programmer.
<asterite>
The complexity of the compiler would be the same, I think
<asterite>
Because when you do: a = exp
<asterite>
we need to bind a's type to exp's type
<CraigBuchek>
I've not really used Erlang, but have done some other functional languages.
<asterite>
so when exp's type changes, a's type changes
<asterite>
Well, in Erlang you end up doing: X = …; X1 = something_with(X); X2 = something_with(X1);
<asterite>
Elixir allows you to "reassign" variables
<CraigBuchek>
But I would think it would simplify the logic required to handle this:
<CraigBuchek>
a = false # here a is Bool
<CraigBuchek>
a.length # ok, a is String
<CraigBuchek>
a = "hello" # here a is String
<asterite>
Yes, that's true, it would be simpler for the compiler
<asterite>
but it would make life harder for the programmer
<asterite>
Or maybe I'm biased, because I'm using to having variables be… well, variable :)
<CraigBuchek>
The funny thing is that C allows you to reassign varaibles, but then modern compilers all do SSA (single static assignment) to treat them as separate variables.
<asterite>
I'm used to...
<asterite>
The other problem is this one
<asterite>
if something; a = 1; else; a = "hello"; end
<asterite>
There you are "defining" the same variable in each of the branches
<asterite>
Would you disallow that?
<asterite>
Or simpler:
<asterite>
if something; a = 1; else; a = 2; end
<asterite>
With immutable variables you would need to do:
<asterite>
let a; if something; a = 1; else; a = 2; end
<asterite>
and have the compiler check that you always assigned to "a" before using it
<asterite>
So it will simplify some aspects of the compiler, but make more complex other aspects
<CraigBuchek>
BRB
<asterite>
Sure
<CraigBuchek>
No, I'd allow different branches to do different assignments.
<CraigBuchek>
The thing is, I'm also wondering if allowing reassignment is actually harmful for developers as well as compiler writers.
<CraigBuchek>
And maybe even allowing different types in different branches. (Although I can come up with examples where that's useful — like a factory that generates a Triangle in one case and a Square in another.)
<CraigBuchek>
I suppose things like a += 1 are useful enough to keep reassignment. But I don't remember the last time I needed that in Ruby. When I come up with a situation where I use a+= x, I almost always come up with a way to rewrite it using functional methods like inject or collect.
<asterite>
You can try programming from now on without reassignment and see how it feels
<asterite>
I will do the same thing and report back :)
asterite has joined #crystal-lang
<CraigBuchek>
LOL
<asterite>
No, really! I mean it :)
<asterite>
I don't have a solid opinion because I never tried it
<asterite>
Maybe I'm too lazy and always (well, not always) reassign variables
<CraigBuchek>
Thanks for listening. Most of that was me thinking some things through. And I wanted to know how much complexity it adds to the compiler to allow reassignment.
<asterite>
But I'll try to program like that for some time and see what happens
<CraigBuchek>
I really don't think I use reassignment in Ruby much, if at all any more.
<CraigBuchek>
I'm thinking about it for my own programming language (toy) project.
<CraigBuchek>
Wondering if I should enforce no reassignments, partially as a way to be disciplined.
<CraigBuchek>
And maybe to save effort writing the compiler.
<CraigBuchek>
It's easy to go from no re-assignment allowed to then allow it. Really hard to take reassignment away from programmers once they've used it.
<CraigBuchek>
I suspect I'll be more concious of using it in Ruby now that we've had this conversation.
<asterite>
In general I don't like a programming language to force me to do things the way it wants
<asterite>
at least not things that bother me a lot
<asterite>
But, of course, those things are subjective
<asterite>
I don't bother getting a NilException at compile time instead of runtime
<asterite>
but somebody else might be bothered by that
<asterite>
I'll search in my code base
<asterite>
Mmm… how would you implement Enumerable#max without allowing reassignment?
<CraigBuchek>
Recursion! ;)
<CraigBuchek>
Reminder to self: Need tail-call optimization if not allowing variable reassignment.
<asterite>
:)
<CraigBuchek>
I find the interactions between language features fascinating.
<asterite>
You mean in general?
<CraigBuchek>
Like not requiring parentheses for function calls. It allows you to substitute varaibles and function calls, but then you have to worry about getting the function pointer without calling it.
<CraigBuchek>
Yes.
<asterite>
Yes, that's a problem D is facing
<asterite>
You can do: foo.bar, and that invokes bar… but if that method returns a function pointer, and since you call function pointers doing bar()
<CraigBuchek>
So we just found another of those interactions — you kinda need tail call optimization if you don't have variable reassignment, or else you paint yourself into a corner with max().
<asterite>
Yes… I think max in functional languages is really simple
<asterite>
as well as many other algorithms
<CraigBuchek>
Ruby has a nice mix of functional programming for me.
<asterite>
For me, Ruby is closest to perfection
<CraigBuchek>
But not so much FP that it makes my head hurt.
<asterite>
Like, aside from performance issues, the definition of the language is really beautiful
<CraigBuchek>
Yup. Ruby is as close to perfection as I've found.
<CraigBuchek>
Doesn't mean I don't want to create something better though.
<asterite>
;)
<asterite>
I know what you mean :)
<CraigBuchek>
I figured. ;(
<asterite>
How's your Brilliant language going?
<CraigBuchek>
Opps, That was suppose dto be ;)
<CraigBuchek>
Slowly. The parser lib had a bug, and I didn't work on it until last week, when someone gave me a work-around.
<asterite>
In which language you are implementing it?
<CraigBuchek>
So I have function definitions and calls. But no parameters yet.
<CraigBuchek>
Ruby and Ruby-LLVM.
<CraigBuchek>
Using Rattler parser. It's nice, but the maintainer hasn't done any commits or answered any issues in many months. I thought he might be dead, but he had 1 commit to some other project last month.
<CraigBuchek>
It's a PEG parser, or at least something similar, which I like.
<asterite>
Ah, I see...
<CraigBuchek>
I wish ANTLR 4 still had Ruby support.
<asterite>
I'd recommend you to do a manual lexer/parser
<asterite>
Not because it's a good exercise
<asterite>
but because its not that hard and frees you from these dependencies problems
<CraigBuchek>
Didn't look worth the effort to add it myself, or to have ANTLR generate an AST in text form to send to Ruby.
<CraigBuchek>
I did that back in college.
<CraigBuchek>
I really like the ability to specify the grammar declaratively. I try to do everything declaratively, if I can.
<CraigBuchek>
Oh, the other nice thing about PEG-like parsers is that they combine the lexer and parser.
<asterite>
I'm looking at the source code, it looks nice