Summarized using AI

Getting Fancy on Rubinius

Christopher Bertels • September 29, 2011 • New Orleans, Louisiana • Talk

In the RubyConf 2011 presentation titled "Getting Fancy on Rubinius," Christopher Bertels introduces Fancy, a self-hosted, dynamic, class-based programming language inspired by Smalltalk, Ruby, and Erlang that executes on the Rubinius virtual machine.

Bertels outlines the goals behind Fancy's design, emphasizing ease of understanding and extension, consistency in semantics, and a noob-friendly syntax. This new language also supports features such as asynchronous message passing, futures, and reflexive programming, aiming for a seamless integration with Ruby code.

Key Points Discussed:

  • Background on Fancy:

    • Originally developed as a C++ interpreter, it was ported to Rubinius, resulting in a more concise and faster implementation.
    • Emphasizes the importance of minimal and clear syntax derived from its influences, primarily Smalltalk and Ruby.
  • Language Features:

    • Object-oriented and dynamic with strong support for message passing, reflecting its Smalltalk roots.
    • Features include blocks, tuples, keyword arguments, automatic method definitions, and built-in concurrency using actors.
  • Integration with Ruby:

    • Fancy leverages the existing Ruby ecosystem, allowing the use of Ruby libraries and seamless method calling with both Ruby and Fancy methods.
    • Keywords and method naming conventions are designed to minimize conflicts between Ruby and Fancy.
  • Documentation System:

    • Bertels discusses Fancy's unique approach to documentation generation, calling on objects for their documentation and producing an interactive HTML output.
  • Testing Framework:

    • The presentation highlights the built-in testing library "fancy spec" that ensures comprehensive coverage of the language's standard library.
  • Performance Considerations:

    • The conversation addresses challenges with concurrency using threads and the potential for better abstractions, such as using actor pools.
  • Future Vision:

    • Bertels expresses hopes that innovations within Fancy may influence future iterations of Ruby, showcasing Rubinius as a fertile ground for experimentation with new programming concepts.

The overarching takeaway from Bertels’s talk is that Rubinius and Fancy provide an innovative environment to explore dynamic language design while fostering a rich integration with legacy Ruby code. Fancy encourages programmers to experiment and push the boundaries of language functionality, potentially leading to advancements in both Fancy and Ruby itself.

Getting Fancy on Rubinius
Christopher Bertels • New Orleans, Louisiana • Talk

Date: September 29, 2011
Published: December 12, 2011
Announced: unknown

Fancy is a self-hosted, dynamic, class based, pure object-oriented programming language heavily inspired by Smalltalk, Ruby and Erlang that runs on the Rubinius VM. It has first class integration with Ruby, support for asynchronous message sends, futures and actors, a simple syntax and consistent semantics, object oriented pattern matching that preserves encapsulation and much more. Fancy runs on Rubinius, a modern bytecode virtual machine designed for Ruby. It is the first fully self-hosted language running on Rubinius besides Ruby. This talk will show Fancy's semantics and language features, its integration with Ruby code, as well as how the new implementation for the Rubinius VM works and what Rubinius has to offer for programming language creators alike.

RubyConf 2011

00:00:17.119 my name is Christopher bees that's the German Way how I say it you can just call me Chris uh I'm from Germany um a
00:00:23.439 student at a university in OS Brook which is the town there where I'm from
00:00:29.080 uh I'm doing an interview sh at Twitter right now and uh so I'm in San Francisco right now uh and I'm going to talk about
00:00:35.480 fancy which is a a new Dynamic object oriented programming language that uh
00:00:41.480 runs on rinus uh basically going to show some language features um and then at the end
00:00:48.039 show some like implementation details and like what rinus has to offer uh in terms of functionality for language
00:00:54.719 creators and people that want to play around with that kind of stuff um if you have any questions that are like very
00:01:01.399 related to the slide just raise your hand otherwise for like more General stuff uh we can do that at the
00:01:07.600 end so uh motivation um I've always been interested in in programming languages
00:01:14.600 uh I I did some fun toy languages uh implemented them in Ruby uh I actually wrote interpreters in Ruby which was so
00:01:21.600 slow but uh it was fun Ruby's very expressive and it's fun to play around also there's great tools for it parel
00:01:28.880 parcel generators stuff like that um but fancy started out as a C++ based
00:01:35.960 interpreter similar to like MRI but written in C++ and uh about a year ago um I and another guy uh from Mexico
00:01:43.920 called Victor um we ported to um to rinus within like two weeks or so and uh
00:01:49.920 the interesting thing is that the implementation before was like 14,000 or 15,000 lines of C++ for The Interpreter
00:01:57.200 and then like 7,000 lines of standard library in the language itself and then
00:02:02.439 after we ported it uh to initial version written in Ruby where the compiler was
00:02:07.520 written in Ruby we ended up with like around two or 3,000 lines of Ruby and 10,000 lines in the standard library and
00:02:14.319 it was faster and that's crazy I don't know maybe my C++ isn't that good but I think
00:02:21.120 it's mostly due to uh the rinus guys uh what they've put into the VM so yeah um
00:02:28.720 what fancy what is fancy about it's uh I wanted to create a language that is
00:02:35.319 uh easy to understand and extend within the language uh that is has very
00:02:40.440 consistent semantics so there's like no magic going on and if you want to look at how something works you just look up
00:02:45.720 it look up the method definition and there you have it uh that's well documented as well um so I looked at uh
00:02:52.599 different language implementations um and uh not just Ruby other all kinds of implementations uh um and uh what I
00:03:00.159 found is that there's good documentation at the API level like you know standard Library stuff but not really for the
00:03:06.799 implementation itself so I kind of wanted to change that uh it's supposed to be very Noob friendly like if you're
00:03:13.360 new to the language it should be able to to get the hang of it quite fast uh if
00:03:18.400 not you know that's my fault uh and um without any ambiguities so uh both in
00:03:24.720 terms of syntax and sematics it should be like obvious like when you look at the code like what it's doing um so yeah
00:03:30.239 that are the goals Inspirations uh biggest one probably small talk and Ruby uh those two they're
00:03:37.840 the main inspiration uh then there's IO which is a dynamic language created by Steve dord who ever heard of
00:03:45.040 IO okay uh it's a very interesting language uh and uh uh I took some stuff
00:03:51.000 from that which I'm going to talk about in a bit um and erlang to some extent uh mostly for like prob well we'll see um
00:03:59.799 but the biggest ones are small talk and Ruby uh so from small talk what I took
00:04:05.599 there was that it's well it's objectoriented like Ruby but uh since Ruby is the descendant of small talk you
00:04:11.079 know it all comes back to small talk in the end um it has pure message passing semantics it's uh the thing with small
00:04:19.079 talk compared to Ruby is that small talk has very little syntax whereas Ruby has a lot of Syntax for a lot of things and
00:04:24.960 uh I try to fancy leans more towards the small talk approach where you really
00:04:30.000 don't want to have as much special Syntax for like different edge cases but try to come up with a you know with a
00:04:36.680 system where everything can be implemented uh in terms of the language itself in like some base Concepts uh so
00:04:43.840 message passing is probably the most important one here um it's very Dynamic I'd say it's probably even more Dynamic
00:04:49.360 than Ruby uh although you could do the things that fanasy does in Ruby as well but it it's just not by default that way
00:04:56.720 and we'll see that later uh it's class based like Ruby and Small Talk uh and it's reflective
00:05:02.479 obviously and what I take from movie is there's more than one way to do it uh
00:05:07.840 it's file based whereas Small Talk typically was like image system where you have like a live environment and you
00:05:13.320 don't really edit files this is all file based uh it Embraces Unix it's the
00:05:18.720 literal syntax is quite like similar and um naming conventions I really like the Ruby name conventions so just they're
00:05:25.360 the same oh and it's also a script like in Ruby where the class definition is actually like executable code and you
00:05:30.919 can like just you know call methods within a class definition this is the same
00:05:36.960 thing so IO and and Earl a bit um the the main idea here is that uh that you
00:05:44.360 that fancy provides Lock Free concurrency so you don't have to deal with locking and the way it does that is
00:05:49.840 uh since it's an object oriented programming language and everything's uh done with message passing there's really
00:05:56.400 no reason why not to have asynchronous message passing and that that's what what would what you would call actors uh
00:06:02.440 there's also Futures which uh basically are values that will represent the the
00:06:08.960 value that will be computed in the future um and I'll show some code later so let's look a bit at the syntax
00:06:16.919 and semantics of the language um okay um so here we see uh you know I
00:06:25.639 mean you can just look at it like AR is pretty much the same uh topples Ruby itself doesn't have uh topples built in
00:06:33.240 uh but rinus has them because they use them topples are basically uh fixed size containers where you can just like
00:06:38.479 append new elements to it they're like once you create it it's fixed size but the thing is they're very memory efficient because they can map directly
00:06:44.960 to see uh arrays which are also fixed SI and rinus uses them internally in the VM
00:06:50.840 uh they um to uh for stuff like implementing uh I think hashes and stuff
00:06:56.080 like that lookup tables maybe even I don't know uh but yeah so since rubinus has it I'm I thought why not have it in
00:07:02.599 the language itself because they can be useful and so that's like python style uh Syntax for uh hashes look a a little
00:07:11.000 different and the reason for that is because if you look one line below there's blocks and blocks use curly braces and in Ruby you have curly braces
00:07:18.280 for both hashes and blocks if you use those those that that syntax but that just complicates the parser and it also
00:07:25.000 like I ideally I want like as less Collision or like multiple meanings to
00:07:30.400 syntax possible so uh then you have uh blocks as I said
00:07:36.199 the first one is without an argument where you just print F the second one is a block with two arcs uh and then that
00:07:43.120 Returns the sum and then the last one is uh with the outside in front is a partial block I call it uh it's
00:07:49.159 basically a block that where you can emit the first like the argument and it just injects it in front of that plus so
00:07:56.120 if you say you know one like an array of one two and three and you say map and you pass in this then you get one two
00:08:02.680 three each plus 42 so like 43 44 so um
00:08:08.720 classes look like that uh methods so the thing about Fancy and like small talk is
00:08:14.520 that it's keyword messages so meth methods that take multiple arguments uh
00:08:20.639 you define them in a way that they um arguments are like basically with
00:08:26.280 interspersed into the um method definition uh that makes up for like it turns out
00:08:32.360 to be really good for like DSL type of stuff because uh it almost well you'll
00:08:38.000 see later but like it look it works very well uh it's it can be wordy like if you look at Objective C I think they take it
00:08:44.480 to the extreme Fan's way more chur than that but yeah um but it works well and
00:08:50.240 and if you look at like rails code you're passing around option hashes always anyway so uh I think it's it's
00:08:57.120 okay uh regular expressions work the same ranges the same and then symbol start with a tick because uh we want to
00:09:04.880 use colon within symbol names uh to refer to Method names and stuff like that numbers
00:09:12.240 um lisp someone okay yeah that's list does it
00:09:17.640 like that too anyway um strings oh yeah and we have multi-line strings so if you do triple quote you can have multi-line
00:09:23.959 strings and we use that for Doc strings which are like python style doc strings and I'll show them later as well
00:09:30.120 so um class and Method definitions uh this is like a simple
00:09:37.360 class and the first line there read write slots basically defines getter and Setter methods it's similar to like
00:09:42.839 adder accessor in Ruby um and I passed it a tole I could have passed an array I could have passed actually anything that
00:09:48.560 implements uh the inumerable interface basically um and then this the next line
00:09:55.160 is the the Constructor method um by default like in Ruby Constructors start with initialize but since we have
00:10:01.600 keyword arguments it'll detect that this is a Constructor method and it'll it'll create a class level um uh Factory
00:10:09.440 method that is called New colon H colon City colon and then what we do there is
00:10:14.680 uh this at name and at age and at city um actually means just Auto assign it to
00:10:20.560 that instance variable like in Ruby you would have to now write at name equals name at age equals age um there's really
00:10:27.360 no reason why you should be doing that because that's that's very common right so um yeah you just write like that and it
00:10:34.839 knows what to do and then when there's no body you can just skip the cly braces um looks nicer I
00:10:42.600 guess
00:10:55.320 yeah oh uh when you when you create a new uh object basically basically like what's your question
00:11:03.560 sorry
00:11:10.200 yeah yeah oh yeah because it's a Constructor so there okay so um a method that starts
00:11:19.160 with initialize is automatically called when you're creating a new object and uh the way the when you create a new object
00:11:26.000 works like this you say person new colon and then you put in first argument so when you create objects and you call
00:11:32.279 Constructor uh the first argument doesn't have a special
00:11:37.320 keyword but the RIS does have like so it would always be new colon whatever class
00:11:43.040 you do but uh it's not really a problem because in Ruby you don't have anything named so you know it's it's not that
00:11:54.079 bad oh because I say at name that's the name of the instance variable like
00:12:01.079 or does that make sense
00:12:08.560 uh yeah exactly yeah so this is this is just like Ruby like in Ruby you can just
00:12:13.600 refer to an instance variable whenever right and you do add or accessor and you pass in like the symbols of the where
00:12:19.959 you want getter and met Setter methods for and so this is the same thing
00:12:26.040 basically yeah
00:12:31.120 uh I guess I'm not
00:12:39.800 sure oh so the don't so what I think you're confusing the method name and the arguments to it
00:12:46.680 so whatever ends with a colon is actually part of the method so that method is called initialize colon age
00:12:52.199 colon City colon that's the name of the method and then the arguments you put in between so yeah
00:13:00.040 like in Ruby you just call initialize and then you just pass pass three arguments but the syntax Works in a way
00:13:05.560 that if you have multiple arguments you the methan name basically changes which is the interesting thing about that is
00:13:11.920 that you can't have like aity errors because the syntax doesn't allow it you know and that's kind of interesting for
00:13:18.600 dynamic languages like it prevents not a lot of bugs but like it does help sometimes y
00:13:35.560 Yeah Yeah so basically what that means at a compile time Rec it creates uh uh a
00:13:41.399 new call that starts with new basically so you basically just substit initialize with new and then that's a class method
00:13:47.720 like in Ruby yeah uh doesn't matter well initialize
00:13:55.800 colon would create a new colon method initialize just like that if you don't need any arguments it will create well
00:14:01.199 by default there's a new method in class class is defined so yeah um all right at the bottom the so
00:14:10.160 you might notice like sometimes the the syntax highlighting isn't that nice uh I have to work on that basically but yeah
00:14:16.320 uh we have the same it has the same thing like in Ruby where you can like insert uh strings into or values into
00:14:23.079 Strings and stuff like that yes
00:14:30.800 so you can do that too you can do like object subass person uh I don't know um
00:14:38.759 there's yeah I don't know uh I like like that basically uh just like for like common
00:14:46.240 things I think syntax having syntax makes sense uh although I can understand your argument but in the end like in
00:14:53.160 terms of like semantics it's exactly the same thing there's no difference really so cuz like this is still executable
00:14:58.680 code right right like doesn't matter um okay flow control so uh here's an
00:15:06.680 example of if then else basically uh what you'll see here this is actually
00:15:12.240 like there's a method called if then else it takes your arguments first argument is some
00:15:20.759 value sorry what that's really awesome okay anyway and then two blocks so the
00:15:27.399 thing in fancy is blocks are first class you don't have there's no special Syntax for it anything that's within like cly
00:15:32.920 braces is a block object and they're just normal parameters so uh yeah that's
00:15:38.480 actually all how all the control flow looping stuff works uh yeah while do there's this stuff like
00:15:47.199 Ruby you can put the if at the end it's the same thing here basically
00:15:55.560 uh why oh yeah so I'll show some bite code later typically fancy code the way when
00:16:02.720 it compiles the bite code is just send send send send everywhere everything's send uh okay um so actors right um yeah
00:16:14.399 so it's it's a message passing and actors basically are concurrent objects uh they're they're asynchronous you send
00:16:21.120 a message and you don't get a value back or in terms of uh Futures you do get a value back but that points to the value
00:16:27.480 that will be computed so uh there's Syntax for that because it's very useful uh and so the way you send an
00:16:33.639 asynchronous message is you just put two add signs between the receiver and the methan name and that's it and it returns
00:16:40.279 nil immediately but what it does it it sends it to the object's actor so in fancy every object can be an actor and
00:16:47.360 the way it works is basically the first time you send an asynchronous message to that object uh it spawns an actor which
00:16:54.000 is which right now runs in a thread um and then but there's different ways to Implement that and uh and it is a it has
00:17:01.480 a mailbox in a in a actor Loop basically similar to like llang or other languages
00:17:06.839 where where basically you don't have to think about uh synchronization because
00:17:12.120 the mailbox ensures that messages get processed first in first out uh so if
00:17:17.559 you send multiple messages it'll only process one at a time and so in the within the actor you can do mutation
00:17:23.679 because you're guaranteed that nothing is happening concurrently within the actor um anyway
00:17:29.880 um and then future sends are similar but you get a value back and you just use one add sign and the value is a future
00:17:36.600 future send object which if you call Value on it you get the value back and if the computation hasn't finished yet
00:17:42.679 it'll block the thread that tries to call it um IO has transparent Futures
00:17:49.240 and I have a branch for that uh and I might actually make that the default but for now you have to call Value
00:17:54.720 explicitly if you use transparent Futures the benefit of that is it's totally comp imposible with any other
00:17:59.760 API because they don't even have to know it's in it's a future so anytime expect a normal value could pass
00:18:06.159 a future send into it and uh it would implicitly call Value if the value hasn't been computed yet but yeah that's
00:18:12.320 that's I'll do that maybe sometime uh so here's a short example um
00:18:18.280 this is like a typical like earing style
00:18:25.720 yeah yeah so you can you can you can also register callbacks you can do that
00:18:31.840 but yeah so it's possible um uh small actual example a ring um if
00:18:39.400 you know llang there's like this Benchmark like there's an example and a simple thing it's basically a list of
00:18:44.440 nodes that send like list of actors that send a message around and then you basically look how long it takes uh
00:18:51.400 actors uh ear Lang is really fast because they have lightweight processes I wish rubinus had something like that
00:18:56.440 but uh for now I have to use threads and the current implementation the way it works is it uh it spawns a thread per
00:19:03.200 actor so that's that works fine until you hit like a certain amount of actors because you don't want like 10,000 of
00:19:09.679 threads uh running on your system so there's another way to do that with a thread pool and stuff like that and and
00:19:15.679 I had I have an implementation of that but the current one just uses the rinus actor API which spawns a thread per per
00:19:22.200 actor um so we have a Noe class and it takes two arguments it takes a next node
00:19:28.000 and and a ring object which is like the manager or whatever and then you it has a count method that takes a current
00:19:34.320 count and uh if it's if it's done like if there's no next object because it's nil you uh just say I'm done and you
00:19:41.320 tell the ring you're finished otherwise uh you print One Dot and then you send to your next uh node the incremented
00:19:48.840 count the ring is looks like that you basically specify how many nodes you want um you create basically a link list
00:19:56.520 uh of nodes and then uh you start it and you finish and then that's the code at the bottom that actually starts it so
00:20:02.960 you say ring is a r new ring with 4,000 actors uh you say start and you give it
00:20:08.200 the current thread so it knows like which because you don't want to like finish right away because if I would wouldn't have the last line the thread
00:20:14.200 stop there uh the script would just finish because you know it starts threads but the main execution thread is
00:20:19.720 just going to finish so I give it the current thread and then I stop and then it will um run like resume me in the
00:20:26.520 Finish method on the left uh show this real
00:20:32.120 quick so right
00:20:37.679 see so I I run this and uh you will see it's not it's not like airling super
00:20:43.120 fast but again this is 4,000 threads and I do kill them uh uh after they've been
00:20:49.679 spawned but for this example probably uh uh threadpool would be what much more better yeah anyway so yeah there you go
00:20:58.840 oop so it definitely works uh performance is definitely uh think something that can be worked on but
00:21:04.919 usually if you have like a system where you want to use actors you shouldn't be have like you can have them but it
00:21:11.640 probably makes more sense to have like certain certain roles of your application be within an actor and then
00:21:16.799 uh you won't have like thousands of them um I don't know okay so
00:21:26.200 back yeah yeah the first implementation what's
00:21:32.960 using fibers uh yeah
00:21:38.520 definitely no yeah uh I have a fiber implementation I have a threadpool implementation I have the current One is
00:21:43.720 using the actual Library I'm still playing around but like if anybody else wants to like you know see what how that
00:21:48.919 works uh it's definitely possible um yeah it's basically just work you have to do that's it but I still I think I
00:21:55.400 have still have to code around somewhere
00:22:02.159 uh
00:22:07.600 yeah oh yeah sorry so um there's two special operators in fancy the dollar sign and the dot operator uh dollar sign
00:22:14.960 is like an it's taken from hcll basically it means everything to the right of it is one expression and pass
00:22:20.840 to whatever is on the left so in this case thread current uh is on the right
00:22:26.320 side and it's one expression and pass to the the start method the reason it works like that is fanasy syntax Works in a
00:22:32.919 way that everything is left to right only like um you always go from left to
00:22:38.400 right and uh yeah no not right now uh I could so the
00:22:47.400 reason why it's actually interesting why I don't have that small talk has it and and most uh keyword messaging based uh
00:22:54.200 systems do have it um but if you use dollar and do you actually save a
00:22:59.600 character because you don't have to do paren and for keyword if keyboard ARS yeah you sometimes have to use
00:23:05.880 parenthesis um but and I don't know I I might fix that uh I haven't been haven't
00:23:12.760 seen many cases where it's super annoying or very annoying or annoying at all um usually if you have well my my
00:23:20.240 take on it is if you have methods that take more than two arguments or three it's too much anyway because then you
00:23:25.760 should probably like encapsulate that in a new abstraction uh and so you usually end up with like
00:23:31.600 at most three arguments to a method maybe sometimes more but yeah usually that's a bad sign so uh I'd say refactor
00:23:50.279 that oh yeah no I don't do that I just passed an array done yeah
00:24:01.799 sorry no no it's all one yeah
00:24:07.880 yeah okay uh so yeah fancy runs of rinus and it would be a shame if we wouldn't
00:24:13.720 integrate with rubby right uh there's so much code out there cool stuff libraries uh and just like being able to use a
00:24:20.159 standard Library I don't want to reimplement all that stuff so uh fancy has I think pretty good integration with
00:24:26.279 Ruby um not just at the bite code level obviously that's that's no problem but also like syntactically and like how how
00:24:33.039 the the semantics work so the idea is if you have like so there's a lot of things
00:24:39.640 that that um in fancy uh uh
00:24:45.480 are how do you say it um like like the standard classes like
00:24:50.799 standard Library stuff uh there's cases where we have a fancy version of a method and and it has the same name
00:24:57.840 basically as a ruby method and the way the method names work and fancy is you either have no arguments so there's no
00:25:04.640 colon or you have arguments and there is a colon and um for the colon version is not a problem because Ruby doesn't have
00:25:11.399 colons in in methan name so uh there's no conflict basically uh for no argument
00:25:17.640 methods they can conflict just by the name they could conflict with Ruby methods that have the same name but might take multiple arguments or stuff
00:25:23.480 like that uh and so we prefix those basically with a colon so no method
00:25:29.640 argument methods start with the colon uh you don't have to deal with that the the language just does it at compile time uh
00:25:36.000 and uh if you want there's a ruby gem for fancy so you can actually use fancy within Ruby uh and there's a little
00:25:42.520 helper syntax that not syntax like a little DSL thing that uh abstracts out way
00:25:47.880 too um but yeah uh so there's special syntax we calling on to Ruby and here's like an
00:25:53.919 example where we basically reuse what's there uh so at the top we Define like aliases because uh the way uh we don't
00:26:02.279 want to like conflict with that we might have different semantics for like say some operation like some method so what
00:26:08.000 we do here is we uh in this case we just Alias them but we have to do that explicitly otherwise uh it wouldn't know
00:26:14.760 what to what to call uh and then in the in the Constructor
00:26:20.320 method you can see it's it's uh I'm just calling out to Ruby and the way that works is you always use explicit parns
00:26:26.960 and that's how B basically so you basically just skip the dot that's it
00:26:34.399 yeah yeah yeah because I want to use a lot of their functionality but yeah uh
00:26:40.559 most a lot of the standard Library reuses Ruby classes there's a bunch of stuff that isn't in Ruby so that's
00:26:46.080 basically homegrown but and it's usually a mix so I actually separated the code like if you look in the in the standard
00:26:51.640 Library there's uh there's lib and then there's lib SL RBX and that's all the extension stuff like that that deals
00:26:57.520 with Ruby stuff and then there's just lib and in there everything's pure fancy there's no doesn't even know necessarily
00:27:03.559 there's Ruby behind it um yeah and that that would be interesting if you wanted to Port it ever like Port it to a
00:27:10.120 different system you could just use the lip stuff and you know do the other thing but uh I'm not really intending to do anything but uh maybe someone would
00:27:18.440 so um yeah we could even pass like blocks and this is actually not the real definition of reject I changed it a
00:27:24.279 while ago but uh just wanted to show the % uh thing that works as well we even
00:27:29.960 can pass like Splat arcs and stuff like that so so the idea with fancy is uh that
00:27:37.279 Ruby is pretty similar too but the idea is that everything should be first class and rubinus is a great platform for that
00:27:43.799 because you know it's implemented almost entirely well not entirely but at the language level and the libraries and
00:27:51.000 stuff like that everything's implemented in Ruby so uh so fancy tries to be have as
00:27:57.679 much first class as well um as I've mentioned blocks are first class so uh
00:28:03.120 and actually that's that's really interesting um you can do that in Ruby of course you can pass lamb lambdas
00:28:08.440 around or like Pro or stuff but uh having it like just natural in the language makes a lot of sense uh so you
00:28:15.039 can do things like each in between that's a method it takes two blocks and it calls the each for every aru um for
00:28:20.600 every element in the list and calls the in between Block in between each of those so uh you can do like this is use
00:28:28.440 this is the array inspect method basically and it creates a string yeah
00:28:34.799 that's what it does uh another thing that's first class in Ruby uh Ruby in fancy is uh
00:28:42.120 documentation so uh fancy doesn't have a docu a documentation parser like Roc we
00:28:48.039 have a documentation system called FOC but it's uh the way it works is it's
00:28:53.559 not actually parsing anything it's it's loading up fancy and then asking every object in the system give me your
00:28:59.120 documentation and then you don't have to parse anything and since I'm lazy and I like documentation but I don't want to
00:29:04.640 write another parser because I hate parsers uh that works out very good uh
00:29:09.760 so this is like a sample like standard uh uh documentation string um and we
00:29:17.559 have like this convention that if you um prefix something with an ad sign it gets
00:29:22.600 like specially highlighted and in terms of the way we do it is like at the top you define the argument names what the
00:29:28.720 what the role is and and the return value and so if you like you see like add block refers to the block argument
00:29:35.159 and then at block at actually creates a link so you can click around between
00:29:40.440 class that that's that links to the the block class when you look it up in the browser so we have HTML version of the
00:29:46.080 documentation and you it's like interactive and then there's like
00:29:51.120 indented is some uh uh some sample code that explains what the method does and
00:29:56.679 that also gets specially formatted because it's indented we use uh our discount the gem to generate HTML uh and
00:30:04.519 then that's the implementation so that's actually pretty common for fancy code you have like a huge chunk of like just dock strings and then like two lines of
00:30:10.360 code and uh it's kind of cool um
00:30:16.559 yeah so here's a video uh showing me the documentation system and the way it works is we generate we start up when we
00:30:24.200 call FOC um it's a little command line tool and it uh it loads up all of fancy and it
00:30:30.600 registers a little hook uh and I can show that in a sec but uh just watch this for a sec so we have like you know
00:30:37.480 instance methods and they like clickable and stuff I think this uses jQuery uh
00:30:42.799 and then here you see the documentation like format it and stuff and that's that's a cool thing if you click on that
00:30:48.000 it was a little octocat you jump to the definition on GitHub with uh highlighting which I think is cool
00:30:55.919 uh yeah all um oh yeah and then you can click on
00:31:02.840 block there and it jumps to the block definition and so
00:31:08.960 um uh what do I want to say um oh yeah so the way it works is um
00:31:16.600 we basically uh if you look at the the general buy code uh these stock strings they actually compile to message SS that
00:31:23.600 um so when you when you load a class file uh what it does is executes it and then within that after that class
00:31:30.000 definition or after every method definition it calls a documentation colon method I think it's called Uh and
00:31:36.240 that registers that documentation with that object and for fog what we do is before we actually load all of fancy we
00:31:42.399 just insert a little hook there and say not not only just Define the documentation for the object but also
00:31:47.919 like registered somewhere else so we can like generate the the documentation for it later um and then we just at the end
00:31:54.840 we just emitted huge chungle of Json and we used jQuery and some stuff in the
00:32:00.200 this so it's all Dynamic basically um so this is the definition of FOC and
00:32:07.279 it uses fog to document itself which is kind of cool uh so you can look at the documentation for fog within FOC um it's
00:32:15.159 not really interesting but yeah so F first class uh also Yeah
00:32:26.000 question oh oh that's nested class okay yeah so uh nested class names you refer
00:32:32.799 to them by space just space and uh this is this just means it has been defined
00:32:38.440 before I think if you wanted to Define it on the spot a new NE class you say class Fu and then within that class bar
00:32:45.360 and then you know like that all right so uh methods for class uh as you
00:32:54.440 might know uh rinus has compiled method objects so methods are already objects and and rinus and I think M Ruby can
00:33:02.799 refer to them too but uh yeah so if you if you define a the way the syntax works
00:33:08.880 I think this is the same for rinus for Ruby on rinus is a method definition is actually it returns an object so you can
00:33:14.880 refer to that and you could like just in line with a syntax you can do like inspect and if you do that in a in The
00:33:20.440 Interpreter it'll you know give you a compound method object um why is that interesting so this is Ruby supports
00:33:27.559 this too but I think it's it's a very important concept the same thing for like first class uh objects uh classes I
00:33:33.720 mean is uh that um you could do things like you know have a test like have a list of tests associated with every
00:33:40.240 method so um fancy has a the testing Library which I will show in a second I
00:33:45.679 don't have it like it's currently com commented out because it didn't work very well but ideally you if you want to
00:33:51.080 if you have testing and and you want to make sure you have good test coverage the way you could like do that is as a first step to basically look at every
00:33:58.240 method in the system and ask it for its qu uh tests and if it doesn't have any tests you should probably write one so
00:34:04.320 that that's and again you save a lot of special effort for that
00:34:11.879 second come on okay um so speaking of testing uh there's
00:34:20.079 fancy spec which is basically an rspc like testing library and it's it's pretty lightweight it's like 430 lines
00:34:25.960 of code but it in ter like it all covers everything I need for now um all the
00:34:32.359 standard library is tested that way and I I wrote this like when I was still working on the C++ implementation so
00:34:39.359 this helped a lot from when migrating to rinus because uh I basically I never tested the the C++ implementation itself
00:34:46.520 just the standard library and the the the runtime behavior and by the time all those tests passed on reinius uh well it
00:34:53.599 worked like so that was kind of cool um yeah so that's very nice and here's like
00:34:59.800 an example how it works so you say fancy spec describe array with and you pass a
00:35:04.920 block and in there you can say it contains three number values after adding them with the uh shift or
00:35:11.160 whatever oper insert operator when and then when array is one to three and the array size is three uh so and what you
00:35:18.680 see here is first of all we we say explicitly what class we're using and that's the same for our spec but then we
00:35:24.359 also Define uh the method name and that's what I was referring to earlier you can now associate this this test
00:35:30.839 case with the method of of that class and that's how you could say have a like a simple way of to like figuring out
00:35:38.079 test coverage um in a way uh so that works here's like you can also test like
00:35:44.400 uh uh like exceptions like expected exceptions so you have a block and you
00:35:49.680 raise an exception then you say that block raises the standard error with e where E's message is the message we
00:35:55.480 defined above and uh that'll pass if it's if it actually raises it and so
00:36:03.680 um so here's like a fspc run and it prints dots like spec and stuff like
00:36:11.119 that so uh some other fun stuff uh that fancy
00:36:16.200 has uh has Dynamic scoping if anybody who who has done list before or like closure whatever cool uh
00:36:24.960 so Dynamic scoping is uh is pretty popular in in like list Ty style languages it basically means that you uh
00:36:33.000 you can refer to like variables uh they have they their binding is dynamic so uh
00:36:39.200 say you have this is actually how we do input output in fanasy so you have like Star standard out star and standard in
00:36:46.560 and stuff like that and you can just rebind it within a block and any any method any any execution within that
00:36:53.720 block uh the standard out value will be whatever you you so here here we have
00:36:59.079 let standard out b f and f is just a file in in that block and now I can call any method like I'm calling print line
00:37:05.800 which by default prints on Star standard star uh and uh yeah it's it's kind of
00:37:13.119 like globals but not really because uh they're like they're thread safe
00:37:18.160 basically so they're they're implemented using threat locals and when you spawn a new thread and you have any of these
00:37:24.119 defined they they basically get copied over so you're never in it's not like Global where multiple threads running
00:37:30.720 could like interfere with each other or something uh
00:37:36.160 yeah not yet maybe soon that would be cool yeah um
00:37:45.119 okay other stuff we have fancy has a built-in package system or whatever you
00:37:50.319 can Define dependencies and they're in like fancy pack files this is actually an actual uh definition uh which
00:37:56.720 constants on road he's sitting over there it's a thin wrapper for for uh Sinatra uh so you can write Sinatra
00:38:03.440 applications uh using fancy and that works I've built a simple Wiki with it and you know you can do all the stuff
00:38:09.400 you can do with Ruby basically uh and then you can Define explicit like normal like fancy dependencies and uh Ruby
00:38:16.119 dependencies and version as well if you want to um and then you say F like on
00:38:21.400 the termal you'd say like fancy install rk/ sinatra. FY and what that does is I
00:38:26.599 just use G by default so if you don't specify version it just takes Master you can specify a version then it looks for
00:38:32.200 a tag with that name and it just works with GitHub and downloads it basically and then you can within your code you
00:38:38.079 can say requires anatra or yeah then it works
00:38:44.720 basically so yeah there's there's support for emac this is all the code you saw was like the emac mode and it's
00:38:50.400 not very good it's not like doesn't have like a lot like Auto completion stuff uh
00:38:55.599 and like life support or whatever but but uh that's mostly because I'm not very good in EM list um there's a text
00:39:02.720 made bundle that works has syntax highlighting and some Snippets uh Vim I
00:39:08.040 don't use Vim Brian where's Brian I think you should write one uh
00:39:14.319 because you use them anyway uh yeah other other things like this is
00:39:20.040 just like for language but like rinus has a lot of Cool Tools as well there's like the Boger you get like really nice
00:39:26.079 colorful back traces which which is cool uh if you've ever ever used reinis you might have seen that uh and this is
00:39:32.720 something I wanted to show there's a there's a Das CV option which so fancy DC in a file just compiles it uh
00:39:40.040 explicitly usually you don't have to do that because it does it like at runtime like if you require a file it'll autoc
00:39:45.920 compile it if it hasn't been compiled yet but uh you can do it manually and you can also do like add the V verbos
00:39:52.200 basically and you can actually look at the white code which is really cool and if you've never looked at that who's ever who uses rinus by the way all right
00:40:01.160 so right for the rest this is cool uh
00:40:07.280 wait oh yeah uh actually I'm going to show it now I think I'm so if you look
00:40:14.000 at the actra example uh
00:40:20.920 oh that so here you see like a bunch of stuff um but
00:40:28.440 interesting let see is so we have like uh this is like the ring definition the
00:40:33.920 class and in here uh we do a bunch of stuff basically
00:40:39.359 uh and you can the the interesting thing is here you can actually like see like you know the names and and like local
00:40:45.040 variables uh they show up like for example see
00:40:52.040 uh here yeah so there's basically a comment saying this is the ring uh local
00:40:57.800 variable which we had if you might remember and but that the actual like value for it that gets passed in the
00:41:03.680 bite code is zero because that refers is an index into the uh into the locals uh
00:41:08.960 dictionary or or array topple whatever um yes and the thing is I didn't have to
00:41:16.200 do anything thing for this because rinus has it and I can just reuse it and it works fine and it's really helpful uh
00:41:22.319 same thing for uh um debugging uh and um
00:41:28.760 what else all back traces yeah they're useful uh if you've ever implemented a language and that is self-hosting so
00:41:35.920 implemented in itself there's some really interesting bugs or crashes you can get uh just by changing like one
00:41:42.359 line somewhere and then suddenly the whole system doesn't work because apparently either the the order in which
00:41:47.400 you load stuff isn't correct or this method is used somewhere at bootstrapping time and it just breaks everything and so having good back
00:41:53.839 traces is really important um and uh yeah which is really cool uh okay
00:42:01.359 going to go back anyway um and you can use this with in just from Ruby as well you just do RBX compile dasb and then do
00:42:09.560 that you can also look at uh the generated um intermediate representation for uh the from the jit so the r has
00:42:17.480 adjust in time compiler it uses lvm which is basically API to create uh machine code and there's an intermediate
00:42:24.200 representation which you can look at and you can I think even look at the Mach machine code for
00:42:29.400 Methods at runtime so why rinas um well rinus loves Ruby
00:42:37.240 but in fact rinus actually loves Dynamic languages because uh the way just the
00:42:43.559 way the system works there's when I initially came to rubinus I realized that sure it's it's it's made for Ruby
00:42:49.839 but there's so many things that that uh could have been different like
00:42:55.440 specialized Ruby but that that are actually pretty pretty Broad and and applicable to not just Ruby so the fact
00:43:02.119 that you know blocks are first class objects within rubinus uh they're not first class in in Ruby you have proc
00:43:07.520 objects and maybe that was the main reason to do it but rubinus doesn't care even and stuff like method names can
00:43:14.040 have colons uh uh a lot of things which I found were really cool and made it a
00:43:19.760 lot easier for me to implement a new language on it uh it's very hackable if usually what I do is if I want to
00:43:25.559 implement something new and I don't know how to how to approach it because I'm not sure how the semantics are in the VM or whatever I just or in in the standard
00:43:32.400 library or the compiler that rubinus has uh I just look up the source and dig
00:43:38.319 into it and since so much Ruby code you don't most of the times I don't even have to look at the at the VM level I
00:43:44.640 can just look at at the parts where it's actually exposed into the Ruby layer of rinas which is really cool uh so it's
00:43:51.880 understandable it's very transparent to me um and culturally it's a very good fit uh a lot of the main design
00:43:59.280 decisions for for rinas have been inspired uh to a large deal by Small Talk VMS and self uh which are old
00:44:06.440 Dynamic languages and um well since fancy is like kind of like
00:44:12.319 a small TP dialect if you will that just made a lot of sense to use
00:44:18.000 rinas okay got to hurry up uh so there's the compiler and rubinus has a bon
00:44:24.079 compiler written in Ruby and I basically just subclass it for my B code compiler uh and and basically subass the parts
00:44:32.240 that that that are have to be different and reuse the parts that are that are fine that are the same or similar enough
00:44:38.800 uh the parser is is still the old Bison parser which is a c c based uh parser
00:44:45.839 generator and I use it as a c extension the reason for that is mostly because as I said before I hate parsers and uh it's
00:44:52.119 the least interesting thing to me really and uh uh I was lazy and since I had C++
00:44:57.480 implementation I used it there and I can just reuse it but there's a there's a keg based parser which is a ruby based
00:45:05.000 pars of generator written by Evan Phoenix who also created rinus which is pretty cool uh I just haven't had much
00:45:10.040 time to to finish that but it's there um and what's one thing that that is
00:45:16.559 interesting or notable whatever is that most of the syntax you saw is really just compiles to message sends so stuff
00:45:22.480 like topples for example are actually message sends and uh that's mostly for
00:45:27.760 some obscure reason but it doesn't really matter uh there's uh pattern matching which I'm going to show a bit and uh and stuff like that and it's all
00:45:34.160 message sense so this is like the grammar for like identifiers an example
00:45:39.520 and as you can see I this is a Capi I use for for Ruby and I use
00:45:45.720 uh uh well you can't really see here but I I call the as colon identifier colon
00:45:51.760 method and that works fine and so that's like the definition of it and there just create an ASD identifier and then those
00:45:58.680 are like different identified classes and you can see there's a bite cat method and it reuses the reinus classes
00:46:04.720 when when it makes sense uh okay that was what a skipped
00:46:11.160 that uh so some stuff that you can do with fancy I I think it works well for dsls uh there's there's some stuff I've
00:46:18.720 been working on with that um there's a parsel CHR nator Library which I'm going to show in a bit uh storm which is a a
00:46:26.680 new system we released at uh Twitter I think last week and it's basically a distributed fa tolerant computation
00:46:33.280 system that's horizontally scalable and Ure and guarantees message uh throughput
00:46:40.599 uh and it has a fancy layer like I wrote a little thing that you can actually
00:46:46.079 write parts of uh like distributed jobs in fancy um and then pattern matching
00:46:53.520 which talk about a bit so I wrote this part combinator thing which basically
00:46:58.920 allows you to um in terms of like it allows you to write like parsers but
00:47:04.359 it's uh it's it's not a generator in the sense that you have like a grammar and then you compile that to something it's
00:47:10.000 just normal objects in the language and the way it works with uses uh operator overloading so even stuff like ant an
00:47:16.880 and what in Ruby aren't methods they're all methods in in fancy and then we use blocks to do stuff with them and uh yeah
00:47:24.720 like here for example we refer to uh the underscore just means don't ignore the first one and the second one is
00:47:30.960 greeted and that refers to the first matched thing within the parentheses and the first argument to that block is just
00:47:37.200 the whole thing that you that you pars um and then you can see how it
00:47:42.400 works uh this is I mean you could use this to like write an actual parure for
00:47:47.559 uh for a language I haven't done this just playing around basically but um it kind of shows like what you can do like
00:47:53.359 andand for example is a method and it creates a a new uh combinator basically that only
00:48:00.880 succeeds if the first and the second one parse and you can come up with all kinds of of
00:48:05.960 schemes all right skip um so there's a storm uh this is like how how the code
00:48:12.440 would look if you wanted to to do stuff I'm just going to skip this because we don't really have time uh P matching
00:48:17.839 going to skip that as well uh if you have questions or I'm going to put the slides up so you can look at that
00:48:23.319 there's a lot of stuff uh we use Travis for um uh travisci for for testing and and NCI
00:48:30.760 and stuff there's miense I didn't talk about uh default arguments local returns
00:48:36.160 C extension stuff FYI is like RI it's like you know give me some help on the
00:48:41.800 command line I fancy is The Interpreter and exceptional I didn't show um
00:48:50.079 so basically what this talk should have showed is that rinus is a really great platform uh to experiment
00:48:57.440 with I think mostly Dynamic languages but I think well you could really Implement anything it doesn't really matter uh but I think it suits very well
00:49:04.559 like Dynamic probably also object oriented but I'm sure you could like go around that as well because they have a
00:49:10.359 little hook where you can Define your own uh look up semantics um and the
00:49:15.760 thing is that having a system where that is so approachable and like uh makes it
00:49:21.760 so easy to Target it gives you a lot of tools and and and capabilities allow ows
00:49:27.280 Innovations and and interesting new ideas to flourish within the Ruby ecosystem and I think that's really
00:49:32.640 great because it doesn't mean like I don't know if every anybody's going to ever use fanasy but maybe some of those
00:49:38.240 ideas might make it into Ruby and because people can explore and like just Branch off of rubinus and try something
00:49:43.760 out and if the other implementations think or people think that's a good idea people can just incorporate it uh Maybe
00:49:49.720 not maybe yeah uh and composability and simplicity in the language so I think
00:49:54.839 that's that's a good thing uh there's some things I wished Ruby had different but you know Ruby is popular
00:50:02.319 fancy isn't so I guess just you know maybe people don't agree with me but yeah I think it's it's still interesting
00:50:09.680 uh so basically yeah explore you know fail I failed a couple times and then you just retry and in the end we'll just
00:50:17.000 win hopefully some some cool stuff adamy it's another language on rinus uh it's
00:50:23.720 very not very different but kind of different than fancy uh it it uses macros similar to like list cell macros
00:50:31.319 and does a lot of stuff at compile time like uh Transformations and stuff which is kind of cool whereas fancy mostly
00:50:37.760 like it's pretty like runtime semantics um there's a really cool video on
00:50:42.880 YouTube and I have a link down there and you can get the slides later it's uh it's a really cool video and explains
00:50:48.760 like implementing your own uh small virtual machine for like Dynamic languages uh I thought it was really
00:50:54.599 cool you might want to check that out and then there's also this on like this book called create your own freaking
00:50:59.760 awesome programming language it's a very very simple introduction to programming language design and and writing a parser
00:51:05.599 and stuff like that so that's also cool you should check that out okay I'm done thanks
Explore all talks recorded at RubyConf 2011
+55