asterite has joined #crystal-lang
asterite has joined #crystal-lang
e_dub has joined #crystal-lang
asterite has joined #crystal-lang
e_dub has joined #crystal-lang
waj has joined #crystal-lang
e_dub has joined #crystal-lang
CraigBuchek has joined #crystal-lang
asterite has joined #crystal-lang
e_dub has joined #crystal-lang
bcardiff has joined #crystal-lang
waj has joined #crystal-lang
asterite has joined #crystal-lang
e_dub has joined #crystal-lang
CraigBuchek has joined #crystal-lang
waj has joined #crystal-lang
asterite has joined #crystal-lang
asterite has joined #crystal-lang
waj has joined #crystal-lang
<CraigBuchek> What is the cost / value of allowing re-assignment of a variable?
<CraigBuchek> I can't come up with a good example of where I'd really want to re-assign a variable. At least not in Ruby or Crystal.
Liothen has joined #crystal-lang
asterite has joined #crystal-lang
<asterite> Hi Craig
<asterite> Can you give us an example?
<asterite> You mean a = 1; a = 2 ?
<CraigBuchek> Yeah.
<CraigBuchek> Reading through the blog: http://crystal-lang.org/2014/04/27/type-inference-rules.html and it talks about handling re-assignments.
<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
<CraigBuchek> Wow, macros allow compile-time introspection. Awesome.
<asterite> :)
<asterite> Very little for now, but eventually you will be able to inspect more of your program
<asterite> And did you see the ECR templates? :)
<CraigBuchek> Yup.
<CraigBuchek> I was wondering why you added the run() in macros. Then read the next change in the ChangeLog.
<CraigBuchek> Almost caught up now.
<CraigBuchek> I need to get my Date class into a PR for you guys.
<asterite> Sure, that would be great :)
<asterite> We lack so many std classes…funcionality...
<asterite> BTW, we think we'll shorten the changelog, otherwise it's too long to read (maybe like to a blog post or something)
<CraigBuchek> I didn't find the changlog too long. Perhaps divide each release into sections: Breaking Changes, Highlights, Additions
<CraigBuchek> And a blog entry for each release would be nice, to explain in some more depth.
<CraigBuchek> OK. Gotta go get dinner. Thanks for the conversation.
Excureo has joined #crystal-lang
travis-ci has joined #crystal-lang
travis-ci has left #crystal-lang [#crystal-lang]
<travis-ci> [travis-ci] Build details : http://travis-ci.org/manastech/crystal/builds/29460446
<travis-ci> [travis-ci] manastech/crystal#1225 (master - d4c2e9b : Ary Borenszweig): The build was fixed.
travis-ci has joined #crystal-lang
travis-ci has left #crystal-lang [#crystal-lang]
<travis-ci> [travis-ci] Build details : http://travis-ci.org/manastech/crystal/builds/29460910
<travis-ci> [travis-ci] manastech/crystal#1226 (master - 883fac8 : Ary Borenszweig): The build was fixed.