Hi, I am honored to announce the beginning of the MacRuby project! MacRuby is a version of Ruby that runs on top of Objective-C. More precisely, MacRuby is currently a port of the Ruby 1.9 implementation for the Objective-C runtime and garbage collector. You can learn more about the project on its homepage: http://trac.macosforge.org/projects/ruby/wiki/MacRuby MacRuby is still extremely experimental, but a first release is expected very soon. Enjoy, Laurent
on 28.02.2008 03:43
on 28.02.2008 04:00
> MacRuby is a version of Ruby that runs on top of Objective-C. More > precisely, MacRuby is currently a port of the Ruby 1.9 implementation > for the Objective-C runtime and garbage collector. > > http://trac.macosforge.org/projects/ruby/wiki/MacRuby > > MacRuby is still extremely experimental, but a first release is > expected very soon. > Thanks for this job I am very excited to test it with my new MBP. Best Regards, Stephane
on 28.02.2008 11:34
Laurent Sansonetti wrote: > Hi, > > I am honored to announce the beginning of the MacRuby project! > > MacRuby is a version of Ruby that runs on top of Objective-C. More > precisely, MacRuby is currently a port of the Ruby 1.9 implementation > for the Objective-C runtime and garbage collector. How are you able to implement ObjectSpace without any impact at runtime? Do you disable the GC while ObjectSpace is walking? If not, how do you avoid the possibility that objects may be collected while you are walking the heap? - Charlie
on 28.02.2008 11:50
Laurent Sansonetti wrote: > Hi, > > I am honored to announce the beginning of the MacRuby project! Can you talk about about expected performance? I imagine it's still early days for the project, but being based on 1.9 I'd expect performance to be somewhat similar. However on a few quick benchmarks I've run it seems there's some degradation in MacRuby over Ruby 1.9. Have you started to look at execution performance much yet? - Charlie
on 28.02.2008 15:34
On 2/27/08, Laurent Sansonetti <laurent.sansonetti@gmail.com> wrote: > http://trac.macosforge.org/projects/ruby/wiki/MacRuby > > MacRuby is still extremely experimental, but a first release is > expected very soon. Interesting stuff. After reading some of the material on the macosforge wiki, I'm curious about the keyed arguments design. It sounds like if I invoke a method like this: x.foo(1, bar: 2) Then what happens is that this gets turned into an Objective-C/Smalltalk syntax message selector of foo:bar:, but if I use x.foo(1, 2, bar: 3) then it effectively uses a different selector and uses Ruby parameter semantics with bar: 3 getting mapped into {:bar => 3} the way Ruby 1.9 does it. So what happens if I write a ruby class like this: class C def foo(*a) keywords = a.pop if Hash === a.last ... end end And then, possibly in a separate file, write def quack(duck) # duck might be an instance of C, but is it? duck.foo(1, 2, bar: 3) # I guess this would work in any case. duck.foo(1, bar: 2) # mapped to foo:bar: what does an instance of C do with this? end This also seems to be treading on some of the territory which Matz has indicated he plans to be defining in Ruby 2.0. I'm worried that there's a fork down the road here. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
on 28.02.2008 21:38
On Thu, Feb 28, 2008 at 2:34 AM, Charles Oliver Nutter <charles.nutter@sun.com> wrote: > Laurent Sansonetti wrote: > > Hi, > > > > I am honored to announce the beginning of the MacRuby project! > > > > MacRuby is a version of Ruby that runs on top of Objective-C. More > > precisely, MacRuby is currently a port of the Ruby 1.9 implementation > > for the Objective-C runtime and garbage collector. > > How are you able to implement ObjectSpace without any impact at runtime? Because all objects are being allocated from the same memory zone, so I just have to walk through the zone. (See /usr/include/malloc/malloc.h for more details.) > Do you disable the GC while ObjectSpace is walking? If not, how do you > avoid the possibility that objects may be collected while you are > walking the heap? I have been thinking of this too, it appears that the current code path works well even if a collection occurs right in the middle. I could nevertheless lock the GC during #each_object if there is a problem. It doesn't change the fact that there is no runtime penalty by default (you can use ObjectSpace if you want). Obviously, MacRuby's #each_object is slower, definitely because it returns all objects from the zone, including Objective-C objects too. $ ruby -ve "p ObjectSpace.each_object {}" ruby 1.8.6 (2007-09-24 patchlevel 111) [universal-darwin9.0] 310 $ /usr/local/bin/ruby -ve "p ObjectSpace.each_object {}" MacRuby version 0.1 (ruby 1.9.0 2008-02-18 revision 0) [i686-darwin9.2.0] 8759 $ /usr/local/bin/ruby -ve "framework 'cocoa'; p ObjectSpace.each_object {}" MacRuby version 0.1 (ruby 1.9.0 2008-02-18 revision 0) [i686-darwin9.2.0] 48425 Laurent
on 28.02.2008 21:41
On Thu, Feb 28, 2008 at 2:49 AM, Charles Oliver Nutter <charles.nutter@sun.com> wrote: > Laurent Sansonetti wrote: > > Hi, > > > > I am honored to announce the beginning of the MacRuby project! > > Can you talk about about expected performance? I imagine it's still > early days for the project, but being based on 1.9 I'd expect > performance to be somewhat similar. However on a few quick benchmarks > I've run it seems there's some degradation in MacRuby over Ruby 1.9. > Have you started to look at execution performance much yet? Yes I have been looking at some benchmarks, a few weeks ago. In benchmarks measuring object creation, MacRuby is slower because allocating an object in vanilla Ruby is cheap. On the other side, GC cycles seem to be faster. But it's definitely early to compare performances yet. And there are a few things we can do in MacRuby to improve allocations, and more. Laurent
on 28.02.2008 21:57
On Thu, Feb 28, 2008 at 6:33 AM, Rick DeNatale <rick.denatale@gmail.com> wrote: > > You can learn more about the project on its homepage: > > semantics with bar: 3 getting mapped into {:bar => 3} the way Ruby 1.9 > > And then, possibly in a separate file, write > > def quack(duck) # duck might be an instance of C, but is it? > duck.foo(1, 2, bar: 3) # I guess this would work in any case. True. > duck.foo(1, bar: 2) # mapped to foo:bar: what does an > instance of C do with this? Here, MacRuby will check if duck responds to foo:bar:. If true, this message is sent with 1 and 2 as arguments. If not true, the foo message is sent instead with 1 and {:bar => 2} as arguments. If you're working with pure Ruby objects, the second code path should always be taken. Unless you define foo:bar: in your Ruby class. Note that the key:value syntax to describe a hash pair is available in vanilla 1.9. > This also seems to be treading on some of the territory which Matz has > indicated he plans to be defining in Ruby 2.0. I'm worried that > there's a fork down the road here. I don't really see this as a fork, but more as a port. Most of MacRuby is based on 1.9, because we want to use all the upstream code base. We just use Objective-C when it's necessary to provide a tighter integration with Mac OS X APIs. Because we want people to use Ruby to write complete full Mac OS X applications, without paying the bridging cost. Laurent
on 28.02.2008 22:14
On Feb 28, 2008, at 3:40 PM, Laurent Sansonetti wrote: >> I've run it seems there's some degradation in MacRuby over Ruby 1.9. > Laurent > The most important thing for me re: performance in MacRuby is how well the Ruby code performs for OS X applications, and since MacRuby has no bridging costs the performance is exceedingly better than the performance of bridged runtimes (like RubyCocoa). What's nice is you can still drop into C or Objective-C trivially with MacRuby if performance is critical but for most application logic MacRuby will be quick enough I think. For server based applications that are mostly pure Ruby (like Rails) the raw Ruby performance numbers are important, but it is early and I think performance will pick up. One cool thing Apple did with the MacRuby GC was have it execute in a background native thread so garbage collection does not lock up the program execution flow. Rich
on 28.02.2008 22:52
Hi,
In message "Re: [ANN] MacRuby"
on Fri, 29 Feb 2008 05:56:41 +0900, "Laurent Sansonetti"
<laurent.sansonetti@gmail.com> writes:
|> duck.foo(1, bar: 2) # mapped to foo:bar: what does an
|> instance of C do with this?
|
|Here, MacRuby will check if duck responds to foo:bar:. If true, this
|message is sent with 1 and 2 as arguments. If not true, the foo
|message is sent instead with 1 and {:bar => 2} as arguments.
|
|If you're working with pure Ruby objects, the second code path should
|always be taken. Unless you define foo:bar: in your Ruby class.
|
|Note that the key:value syntax to describe a hash pair is available in
|vanilla 1.9.
I still think having dedicated syntax for Objective-C call is better
than overriding normal call.
duck.foo: 1 bar: 2
or
duck.foo: 1, bar: 2
maybe? I am not sure if the parser allows this or not yet.
matz.
on 28.02.2008 23:54
On 2/28/08, Laurent Sansonetti <laurent.sansonetti@gmail.com> wrote: > Note that the key:value syntax to describe a hash pair is available in > vanilla 1.9. Yes I know, and that's my concern about the possibility of a fork. > > This also seems to be treading on some of the territory which Matz has > > indicated he plans to be defining in Ruby 2.0. I'm worried that > > there's a fork down the road here. In 1.9 Matz has basically set the caller side of keyword parameters. What's left for 2.0 is how to write methods that take them as a substitute for manipulating hash parameters in the input. My concern is that MacRuby might be going down a road which is incompatible with the way Matz eventually goes on the receiving side. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
on 28.02.2008 23:59
On 2/28/08, Yukihiro Matsumoto <matz@ruby-lang.org> wrote: > |always be taken. Unless you define foo:bar: in your Ruby class. > > > or > > > duck.foo: 1, bar: 2 or duck.dispatch("foo:bar:", 1, 2) or any other acceptable name for dispatch, which is an objective-c flavor of __send__. Of course the problem with this is that MacRuby is trying to build ruby on top of Objective-C mechanisms, rather than the other way around. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
on 29.02.2008 00:05
On Thu, Feb 28, 2008 at 1:51 PM, Yukihiro Matsumoto <matz@ruby-lang.org> wrote: > |message is sent with 1 and 2 as arguments. If not true, the foo > > > duck.foo: 1 bar: 2 > > or > > > duck.foo: 1, bar: 2 > > maybe? I am not sure if the parser allows this or not yet. > I have been thinking about this too, but I personally believe that it doesn't reveal very pretty when messaging Objective-C methods with only one argument. duck.foo: 1 But maybe we will switch to it soon, because it's more consistent with Objective-C (no potential ambiguities). But it doesn't feel very Ruby. Laurent
on 29.02.2008 00:16
Hi,
In message "Re: [ANN] MacRuby"
on Fri, 29 Feb 2008 08:04:38 +0900, "Laurent Sansonetti"
<laurent.sansonetti@gmail.com> writes:
|> I still think having dedicated syntax for Objective-C call is better
|> than overriding normal call.
|>
|>
|> duck.foo: 1 bar: 2
|>
|> or
|>
|>
|> duck.foo: 1, bar: 2
|>
|> maybe? I am not sure if the parser allows this or not yet.
|>
|
|I have been thinking about this too, but I personally believe that it
|doesn't reveal very pretty when messaging Objective-C methods with
|only one argument.
|
| duck.foo: 1
You can still map one-argument method to duck.foo(1) as it does now.
|But maybe we will switch to it soon, because it's more consistent with
|Objective-C (no potential ambiguities). But it doesn't feel very Ruby.
That is very important design decision. Objective-C-ish calling or
Ruby-ish calling. The latter makes program consistent, but the former
makes program obvious. Hmm.
matz.
on 29.02.2008 00:18
On Thu, Feb 28, 2008 at 2:58 PM, Rick DeNatale <rick.denatale@gmail.com> wrote: > > |If you're working with pure Ruby objects, the second code path should > > duck.foo: 1 bar: 2 > You can do that right now with MacRuby. $ /usr/local/bin/irb --simple-prompt >> d = NSMutableDictionary.new => #<NSCFDictionary:0x1641800> >> k = NSString.new => #<NSCFString:0xa001b318> >> d.send('setObject:forKey:', 'foo', k) => nil >> d.objectForKey(k) => "foo" (This is just an example.) > or any other acceptable name for dispatch, which is an objective-c > flavor of __send__. You can also use NSObject#performSelector and its variants. >> d.performSelector(:'objectForKey:', withObject:k) => "foo" > Of course the problem with this is that MacRuby > is trying to build ruby on top of Objective-C mechanisms, rather than > the other way around. > MacRuby is only trying to make the better compromise between both languages. We could use a completely new syntax which looks like Objective-C, but Ruby developers won't like it, I think. Laurent
on 29.02.2008 00:33
On Thu, Feb 28, 2008 at 3:15 PM, Yukihiro Matsumoto <matz@ruby-lang.org> wrote: > |> duck.foo: 1 bar: 2 > |doesn't reveal very pretty when messaging Objective-C methods with > |only one argument. > | > | duck.foo: 1 > > You can still map one-argument method to duck.foo(1) as it does now. > Yes, but it won't be consistent with multiple-argument calls then. > |But maybe we will switch to it soon, because it's more consistent with > |Objective-C (no potential ambiguities). But it doesn't feel very Ruby. > > That is very important design decision. Objective-C-ish calling or > Ruby-ish calling. The latter makes program consistent, but the former > makes program obvious. Hmm. > Definitely! I have been thinking about this a lot, but I couldn't come with something better than what's currently in MacRuby. duck.foo # may call foo duck.foo(1) # may call foo: duck.foo(1, key:2) # may call foo:key: There is also the problem of defining methods with keyed arguments. Currently: def foo(x, key:y); end # will register foo:key: Laurent
on 29.02.2008 01:47
On Feb 28, 2008, at 3:04 PM, Laurent Sansonetti wrote: >> |> instance of C do with this? >> available in >> >> duck.foo: 1, bar: 2 >> >> maybe? I am not sure if the parser allows this or not yet. >> > I thought about working up for Objective-C calling support via this syntax: O[duck :foo => 1, :bar => 2] At one point, I had a small parser change that allowed this to be written as: O[duck foo: 1, bar: 2] The idea was that the rubinius compiler would detect this special form and emit the 'right thing'. I think a bit part of this is whether you expect users (and other code) to know they're calling out to Objective-C, or if you want tight integration. This is essential what matz says. By making special Objective-C syntax, then you can't pass in an Objective-C object and expect it to be duck-typed like normal ruby objects. But the trade off is that the syntax is less elegant. I think it's a trade off, and my 2 cents is you should opt for the more elegant syntax. This is because there are only a few tiny edge cases where the Objective-C selector matches the ruby selector, where you'd want to allow the ObjC object to be duck typed as something else. Thus, since the method names are so radically different, it's better that the user know "ok, I'm calling this other kind of method, so I need to use this syntax." If they want to duck-type it, then let them write a wrapper for the ObjC method/syntax: def call_objc(a, b) O[duck foo: a, bar: b] end Something else that has not been brought up (that I saw) is whether ruby methods are available as Objective-C methods. Can ruby methods be called directly via the ObjC runtime? - Evan
on 29.02.2008 02:42
On Feb 28, 2008, at 7:44 PM, Evan Phoenix wrote: >>> > writes: >>> should >>> duck.foo: 1 bar: 2 > I thought about working up for Objective-C calling support via this > form and emit the 'right thing'. > cases where the Objective-C selector matches the ruby selector, > where you'd want to allow the ObjC object to be duck typed as > something else. So in your view: O[duck foo:1, bar:2] is elegant? Elegant Ruby? no. I agree to opt for the elegant syntax and that's: duck foo:1, bar:2 > > > Thus, since the method names are so radically different, it's better > that the user know "ok, I'm calling this other kind of method, so I > need to use this syntax." The method names are not radically different all the time: window.frame #=> NSRect In addition, what happens when you subclass? class MyView < NSView def do_something_wonderful end end Now I have an instance: view = MyView.alloc.init call a Ruby method and then an objc method view.do_something_wonderful frame = O[view frame] I find that visually scary. I think the point here is to actually unify things if possible in a Ruby friendly way and that would be: view.do_something_wonderful frame = view.frame > ruby methods are available as Objective-C methods. Can ruby methods > be called directly via the ObjC runtime? Yes, you can go the other way.
on 29.02.2008 02:48
On Thu, Feb 28, 2008 at 4:44 PM, Evan Phoenix <evan@fallingsnow.net> wrote: > >> > writes: > >> |always be taken. Unless you define foo:bar: in your Ruby class. > >> > syntax: > Your idea is surprising, but how would you do to override an Objective-C method? > I think a bit part of this is whether you expect users (and other > code) to know they're calling out to Objective-C, or if you want tight > integration. This is essential what matz says. > Yes I do agree with that. > ruby methods are available as Objective-C methods. Can ruby methods be > called directly via the ObjC runtime? > In MacRuby, Ruby methods are in fact Objective-C methods, by default. Everything is registered to the Objective-C runtime. Calling them from Objective-C might be tricky sometimes, because Ruby allows some characters in method names that Objective-C doesn't. But using the runtime API (ex. objc_msgSend) should just work. My point is, there should not be any special syntax to call Objective-C methods because all methods are Objective-C methods. Or at least, no extremely special syntax. I do like the current implemented one, as many people so far. duck.foo 1, bar:2 A few people also like Matz's first suggestion, which is to specify the ':' in the first part of the method call, because it's more consistent with the selector that will be sent. duck.foo:1, bar:2 But so far, most of these people are Objective-C developers and not Ruby developers. Laurent
on 29.02.2008 02:50
On Feb 28, 2008, at 8:46 PM, Laurent Sansonetti wrote: > I do like the current implemented one, as many people so far. > > duck.foo 1, bar:2 Oh right, duck.foo 1, bar: 2 ... not duck foo:1, bar:2 :-)
on 29.02.2008 02:56
On Thu, Feb 28, 2008 at 5:50 PM, Richard Kilmer <rich@infoether.com> wrote: > > On Feb 28, 2008, at 8:46 PM, Laurent Sansonetti wrote: > > > I do like the current implemented one, as many people so far. > > > > duck.foo 1, bar:2 > > Oh right, duck.foo 1, bar: 2 ... not duck foo:1, bar:2 :-) Yes you can put or remove spaces, parenthesis, etc... Alternatively, key:value can be replaced by :key => value duck.foo 1, :bar => 2 Which is apparently more Rails'ish. (I personally prefer the first one though.) Laurent
on 29.02.2008 03:19
On 2/28/08, Richard Kilmer <rich@infoether.com> wrote: > > On Feb 28, 2008, at 7:44 PM, Evan Phoenix wrote: > > tight integration. This is essential what matz says. > > duck foo:1, bar:2 Or duck foo: 1 bar: 2 which is even more elegant, since it's the same syntax as Smalltalk <G> Somehow I feel like I'm back in late 1981 or early 1982, when Brad Cox and Tom Love at ITT, I at IBM, and probably others, had read the August 1981 issue of Byte magazine and were trying independently to graft Smalltalk onto C independently. Brad, Tom and I later became friends when we met, but Objective-C certainly outlived ClassC which never really got any visibility outside of Big Blue. More seriously, I tend to lean on the side of making things like the objective-c/ruby interface a little more visibility, since I've learned that transparency isn't always what it's cracked up to be. http://talklikeaduck.denhaven2.com/articles/2007/11/17/cool-but-stupid-things-ive-done -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
on 29.02.2008 05:50
On Thu, Feb 28, 2008 at 6:19 PM, Rick DeNatale <rick.denatale@gmail.com> wrote: > > > form and emit the 'right thing'. > > > cases where the Objective-C selector matches the ruby selector, > > duck foo:1, bar:2 > Or > > duck foo: 1 bar: 2 > > which is even more elegant, since it's the same syntax as Smalltalk <G> > The problems with these syntaxes are that it's hard to parse them, and that they can lead to ambiguities when wrongly used. For example, duck.foo: x, with: y could be written by mistake as duck.foo :x, with: y which has a completely different meaning. Also, when the parenthesizes are omitted, it may be hard to correctly parse (assuming that you want to send the message to self) foo:x, with:y That's why I think that the following is the best compromise so far, between readability and reliability. foo x, with:y # or foo(x, with:y) Laurent
on 29.02.2008 05:56
On 2008.02.29 08:15, Yukihiro Matsumoto wrote: > That is very important design decision. Objective-C-ish calling or > Ruby-ish calling. The latter makes program consistent, but the former > makes program obvious. Hmm. Actually, this would be a really great time to talk about trying to unify the keyword argument syntax across implementations so that we do not have to have that discussion later or contend with several variants. I know that we are not at the 2.0 threshold yet, but obviously folks are starting to get there. In the particular case of MacRuby, I would go for implicitness unless there is a reason that the programmer needs to know the difference. If we can define an official syntax (and semantics) for keyword arguments that also helps MacRuby, I think that would be the optimal solution. I would probably prefer one of the Smalltalkish variants as the standard: duck foo: 1, bar: 2 This plausibly conforms to current method semantics: def duck(**kwargs) # Implicit in the vcall sym, arg = kwargs.shift __send__ sym, arg, **kwargs end
on 29.02.2008 13:56
On 2/28/08, Laurent Sansonetti <laurent.sansonetti@gmail.com> wrote: > > foo x, with:y # or foo(x, with:y) One thing that's yet to be mentioned is that the Ruby keyword arguments are position independent so that using Ruby 1.9 semantics: foo(x, a: y, b: z) and foo(x, b:z, a:y) are equivalent, but in MacRuby, as I understand it they result in two different message selectors foo:a:b: and foo:b:a: respectively. I'm something which I didn't comment on in an earlier posting might bear some discussion. I'd posed a situation where a Ruby class had implemented a foo method with ruby 1.9 handling of 'keyword' arguments via an optional hash as the last argument of a *args. then asked >> duck.foo(1, bar: 2) # mapped to foo:bar: what does an >> instance of C do with this? And Laurent responded: > Here, MacRuby will check if duck responds to foo:bar:. If true, this > message is sent with 1 and 2 as arguments. If not true, the foo > message is sent instead with 1 and {:bar => 2} as arguments. > If you're working with pure Ruby objects, the second code path should > always be taken. Unless you define foo:bar: in your Ruby class. I'm concerned here about the automatic 'chicken-type' and branch in the caller, for the performance implications if nothing else. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
on 29.02.2008 14:07
On 2/28/08, Eero Saynatkari <ruby-ml@kittensoft.org> wrote: > get there. > > > This plausibly conforms to current method semantics: > > def duck(**kwargs) # Implicit in the vcall > sym, arg = kwargs.shift > __send__ sym, arg, **kwargs > end Except, as I understand the discussion, here duck is a variable representing the receiver of a message with an objective-c message selector of foo:bar: and which in Ruby might be written as: class PotentialClassOfDuck def foo(first_arg, keywords={}) end end I think that a reasonable Ruby parser would have a hard time seeing: duck foo: 1, bar: 2 as anything other that self.duck(foo:1, foo:2) So I think we'd need to give it some help and write: duck.foo: 1, bar:2 which given optional parentheses might also be written(?): duck.foo(: 1, bar: 2) but I'm not happy with either of those for several hopefully obvious reasons having to do with the dependence on the presence or absences of easily misread punctuation and whitespace. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
on 29.02.2008 22:14
On Feb 27, 2008, at 7:42 PM, Laurent Sansonetti wrote: > http://trac.macosforge.org/projects/ruby/wiki/MacRuby > > MacRuby is still extremely experimental, but a first release is > expected very soon. This. Is. Sweet. I've been working on a hackish interpreter-on-ObjC (though GNUstep) for a while, as an experiment. This sounds like exactly what I had in mind.