tag:blogger.com,1999:blog-19626531.post6502283858912725254..comments2023-11-02T08:32:39.646+01:00Comments on Ola Bini: Programming Language Synchronicity: Ruby closures and memory usageOla Binihttp://www.blogger.com/profile/15793488672952593953noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-19626531.post-82781735156568509082009-03-02T12:16:00.000+01:002009-03-02T12:16:00.000+01:00I mean transform to string using for example ruby2...I mean transform to string using for example ruby2ruby gem.Alexhttps://www.blogger.com/profile/17389389602150855595noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-4779250770317517162009-03-02T12:15:00.000+01:002009-03-02T12:15:00.000+01:00To keep syntax compact you can also define 'lambda...To keep syntax compact you can also define 'lambda2' method.<BR/>That will transform you Proc to string and then reevaluates it in minimal closure.Alexhttps://www.blogger.com/profile/17389389602150855595noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-25088387084849288872008-01-01T16:10:00.000+01:002008-01-01T16:10:00.000+01:00As I reread my comment, I see a number of small ty...As I reread my comment, I see a number of small typos. <BR/><BR/>The first couple of sentences may be a little awkward. Particularly klunky is the second sentence which might be better written "But also a tension between optimized code <I>and</I> programmer ability..."<BR/><BR/>After option 1. and 2. there is of course option 3. - do nothing. And the example with a case statement should have a variable name in both the <B>case</B> and corresponding <B>if</B> expressions. That is "<B>case</B> <I>x</I>" and "<B>if</B> <I>x</I> >= 4".rockyhttps://www.blogger.com/profile/15499462357824396668noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-32415956656101724202008-01-01T13:31:00.000+01:002008-01-01T13:31:00.000+01:00There seems to be a tension of between optimizer a...There seems to be a tension of between optimizer and dynamic language. But also a tension between optimized code at the <I>expense</I> programmer ability to understand what's going on let alone effect what goes on there or introspect at run time on the other side.<BR/><BR/>I like dynamic languages; I like optimizers and fast code too. And I don't see why I should have to give up either.<BR/><BR/>Rather, I'd like to see an ongoing dialog between the program and the transformation system.<BR/><BR/>So rather than resigning to the fact that a transformation can't optimize closures in Ruby, why couldn't that system indicate the consequences of that code and ask: would it be alright here to remove the outer scope in this closure here? The choices might be:<BR/><BR/>1. okay do the transformation at the source level, or<BR/><BR/>2. do it in the optimization phase without changing the source code, possibly adding in some annotation comments about indicating the transformation.<BR/><BR/>In other words, too often optimization tends to be a static, overly conservative process that doesn't interact with the programmer. This is sad because there's lots of information the programmer might be able to offer that could be used to great benefit.<BR/><BR/>Similarly there's lots of information that a code improver can offer to inform a programmer regarding how to speed up the code. <BR/><BR/>In some cases the programmer may decide to change the source code. In other cases maybe the programmer would rather have the compiler system make the changes on its end. <BR/><BR/>Here's an example of the former. Suppose I write "([1] * 10).size == 0". Unless size() is redefined on Arrays which probably won't be the case, a compiler could just replace this with "false" which will probably be more efficient if not clearer. Maybe this seems like a silly thing to write but it could fall out of propagating constants. I know that I've written things like "x.size > 0" where "x.empty?" might be more efficient. And I've written "x.class == String" instead of "x.isa?(String)" because I didn't know about "isa?".<BR/><BR/>In these cases an optimizing system could educate and <I>inform</I> the programmer and make possibly the person a better Ruby programmer. In these kinds of cases, a concerned programmer might change the source code to those other forms.<BR/><BR/>Here is another situation, also from real life. However in the following, I think a user would <I>not</I> change code but ask the transformation system do it internally.<BR/><BR/>I once worked on an optimizing compiler that had a case statement similar to Ruby's. You could write "case ; when 1 ; when 2; when 3; when 4; when 1000; when 2000; ... end" If there are lots of "when" clauses a good way to implement this to sort, the "when clauses" and do a binary search on them. So first test if >= 4 if so try the appropriate sets of when clauses based on this outcome. For example if the value we would less than 4 then we'd test if >=2 and so on. In theory a person could write the code an optimizer could transform the code into, but in practice this is cumbersome, ugly, prone to mistake, and not robust if "when clauses" are added or removed.<BR/><BR/>I'm not suggesting the above is really that new if at all. There currently are "lint" systems that critique one's code. However most of the ones I've seen aren't that interactive, are separate from the optimizer, and won't change code.rockyhttps://www.blogger.com/profile/15499462357824396668noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-58369986348571022262007-12-28T06:55:00.000+01:002007-12-28T06:55:00.000+01:00flgr, I've been saying that for years now. many bl...flgr, I've been saying that for years now. many blocks do not need the closure. I bet performance gain would be fairly substantial too. I wonder if matz hasn't embraced this simply becuase of implementation difficulties?tea42https://www.blogger.com/profile/02848516783203845093noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-18504098321835241482007-12-26T16:52:00.000+01:002007-12-26T16:52:00.000+01:00About creating a minimal binding, I just realized:...About creating a minimal binding, I just realized: wouldn't the following suffice?<BR/><BR/>block = class << Object.new; proc{ ... } end<BR/><BR/>A bit shorter than defining a method, and fits (somewhat) in one line :) Or am I missing something here?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-19626531.post-18810051512951175162007-12-26T12:09:00.000+01:002007-12-26T12:09:00.000+01:00I agree we could use this for some discussion over...I agree we could use this for some discussion over how the language could be best adapted to improve performance. Maybe if binding became a keyword, and eval strictly a method of it (that is, no Kernel.eval)? There could also be an "eval" keyword that would be short for binding.eval, but personally I don't think even that would be necessary. That way, I believe, it would be clear whenever the full binding would be involved in a closure.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-19626531.post-45563992628554204682007-12-22T15:43:00.000+01:002007-12-22T15:43:00.000+01:00ola: Naturally... *slaps forehead*Myself, I tend t...ola: Naturally... *slaps forehead*<BR/><BR/>Myself, I tend to use eval very rarely in those languages that support it. Seeing as it seems costly to include it in a language, I presume it must be valuable. Is there any eye-opening information on the web on the use of eval?Tomashttps://www.blogger.com/profile/14474896952223748449noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-82877589099613489632007-12-22T14:46:00.000+01:002007-12-22T14:46:00.000+01:00Or you could constraint the ways reflection/eval c...Or you could constraint the ways reflection/eval can access variables from the lexical scope - which would mean changing the language, of course. So that you would have a better chance finding all the variables to close over.Johanneshttps://www.blogger.com/profile/17243632157564129686noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-75367941902340149672007-12-22T11:41:00.000+01:002007-12-22T11:41:00.000+01:00@ola biniYou are right. Even if we would develop a...@ola bini<BR/><BR/>You are right. Even if we would develop a complete typing system that would detect wether or not the the block would actually use eval-in-any-way, there are 100 other ways of reflection that could mess it up.<BR/><BR/>Imagine a block that tries to list all the properties in its own scope. It doesn't explicitly refer to any variables.<BR/><BR/>Any type checker that could figure out it would use reflection anywhere without a doubt would definately hit the halting-problem.<BR/><BR/>But it should be possible to make a pretty good guess on the safe side. That is: we can write something that says 'it doesn't use any reflection, it doesn't refer to variable X, we don't need to close over variable X' ..Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-19626531.post-36962011927055167242007-12-22T00:09:00.000+01:002007-12-22T00:09:00.000+01:00But eval is a very rare case. My suggestion would ...But eval is a very rare case. My suggestion would be to make eval syntax (makes it impossible to use e.g. send(:eval, code) which I've never seen and probably nobody uses anyway) and optimize the 99.9% of procs/blocks that don't use eval. Those with eval - just enclose as it does now.<BR/>Or do I miss something else?shisohanhttps://www.blogger.com/profile/01243557588884271327noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-87369685085740758042007-12-21T22:39:00.000+01:002007-12-21T22:39:00.000+01:00Tomas: yes, there is a marvelous reason for this: ...Tomas: yes, there is a marvelous reason for this: eval. There is no way for the parser to know which variables will be used at any point. The price you pay for a VERY dynamic language.Ola Binihttps://www.blogger.com/profile/15793488672952593953noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-49024953070801631102007-12-21T22:31:00.000+01:002007-12-21T22:31:00.000+01:00Many languages have compilers that perform analysi...Many languages have compilers that perform analysis on the closures and capture only the variables it actually closes on; This includes the "self" variable of the instance. This is not currently the case with Ruby? Is there any reason why the compiler could not be implemented in such a way?Tomashttps://www.blogger.com/profile/14474896952223748449noreply@blogger.comtag:blogger.com,1999:blog-19626531.post-82749433926110163332007-12-21T19:16:00.000+01:002007-12-21T19:16:00.000+01:00Hm. Would it make sense to define a built-in separ...Hm. Would it make sense to define a built-in separate { ... } construct that would establish a separate scope? One case where this would be quite useful is finalizers.<BR/><BR/>I'm not sure how important it is to be able to selectively pull new variables into the scope. It's hard to come up with an intuitive and simple syntax for that. separate(a, b) { puts a; puts b } has an odd feeling to it in my opinion...flgrhttps://www.blogger.com/profile/05128769452612477118noreply@blogger.com