Rooftop Ruby Podcast

2: Going Deeper by Getting Broader

February 10, 2023 Collin Donnell & Joel Drapper Episode 2
Rooftop Ruby Podcast
2: Going Deeper by Getting Broader
Show Notes Transcript

Collin and Joel discuss lessons they’ve learned from studying other languages, internet connect troubles and successes, and more.

Follow us on Mastodon:

Show art created by JD Davis.

Collin:

Hey, Joel, how's it going this week?

Joel:

It's, um, it's going all right. I have not had internet all week at home, which has been challenging to say the least.

Collin:

Yeah, so let's, uh, let, let's, let's give some context on this. We, we published the first episode of our, of our podcast, and then we're like, all right, a couple days later we are gonna, You know, record another episode and then, uh, your internet went out like the day or the day before we were going to do that.

Joel:

Yeah. It, it went out on the 24th of January and it's now the 8th of February and it's still not back.

Collin:

That's wild. Do they have any timeline or whatever? How is that, and how has that affected you being able to, you know, do your job as a professional programmer? Right. You have to do a lot of, uh, you know, using the internet. I, I feel.

Joel:

Yeah. I've, I've managed to get by to some extent using tethering from my phone. Um, my house is in kind of a bit of a 3G dead spot, but I've, like, over the last few days, found the ideal spot to like, place my phone by the window where I can tether, but it's been pretty bad. Um, like to the extent that, well, so they've been updating me every single day, but their updates are just like, we hope to have it fixed. Today and they say that every single day. Um, and now I've just like gone ahead and, and got a like backup internet connection, but that's not gonna be installed until the 15th, so I'm just kind of getting by.

Collin:

Yeah, that's wild. I, I, I have no plan for if my internet went out for two weeks, but I think all of, uh, ours here is. Uh, overhead wires. So I think it would be more difficult. They wouldn't have to dig up the street if it went out. At least that's what I hope in internet connection related news, though, I've achieved what I consider to be like a lifelong ambition of myself and I think most other millennials and maybe Gen Xers, which is that I had a guy come out, uh, I had three, three guys came out. Y. And, uh, ran ethernet, uh, into all of my upstair r upstairs rooms. So I'm all wired now. Yeah, which is pretty great.

Joel:

Yeah, we need to get that done here.

Collin:

Yeah, it was surprising. It, you know, it's not cheap, but uh, it was surprisingly inexpensive compared to what I thought it could be. Like, uh, ended up being like$300 a drop, you know? But like, I only have three rooms, so I'll, there's no more I can do. Like, this is it, this is the most I'll ever need. Um, and so it's like$900, which is a lot of money, but it's not. It seemed like the kind of thing that could have been more, you know, uh, so I was happy about that. Something I found out when they were here was that, uh, my house, I thought it was all plaster or whatever, you know, like they used to do back in the old days. Uh, cuz my house is from 1909 and I found out it's actually all shiplap. Uh, because Portland, Oregon is a pretty wet place. And I guess, uh, shiplap is like interconnected board. I don't even think they're really nailed together. I think they're just kind of like inter uh, jointed together. I, I haven't totally researched all of this, but, um, I found out that is why wifi worked so, uh, poorly because I had, you know, multiple inch thick boards, uh, you know, two of those on each side of the wall going from my router up to my office, right? And so it's pretty bad.

Joel:

Did you have like a mesh network or just a single reader?

Collin:

Yeah, I did. And even then it wasn't great. Uh, surprisingly Um, but anyway, yeah, so that's, uh, well, I'm hoping that your internet gets sorted pretty quickly. Um, that's, that, that really sucks. It sounds like, uh, the backup thing will really, really make things easier.

Joel:

At least. At least I have something to look forward to now because I can't trust the other company that they're actually gonna get me back online at any point because like they're just. they haven't been able to give me any kind of indication, so, um, at least I now know that by the 15th I will be online one way or another. Anyway. How, how was your week, Collin?

Collin:

Oh, my week's been great. Uh, like I said, I did this thing with, uh, the ethernet. I've been working, uh, doing some interesting. I'm working on, uh, swift stuff right now. Mostly, uh, less ruby, more swift. So I'm working with a new UI framework that came out a couple of years ago called Swift ui. You may have heard of, uh, on the internet, which is kind of the modern, declarative way to do user interfaces on, um, a. On, uh, you know, on iOS and Mac and, uh, you know, it's been a little rough cuz it's new and uh, you know, so each year it gets a little better, but I feel like this year has really been one where it has. Crossed over a barrier, at least on iOS. It's still kind of rough on Mac. Um, but it's, it's, it's a neat way to think about doing things in a slightly more, uh, declarative fashion like that, you know, so you can structure things almost a little bit more like you would in a Rails app, you know, where like, you know, HTML is completely declarative, right? So this is sort of, Sort of like that a little bit. Um, although it's still swift code and you can still like, do things with it. Um, you know, so maybe, I don't know exactly what I would compare it to, but it's, it's really neat. It makes a lot of things that were very difficult before, much easier. So that's what I've been working on this week, and that's been, that's been really interesting.

Joel:

Is it a kind of like block based dsl or how, how does it work?

Collin:

Yeah, so that's exactly, uh, how I would describe it. It is, it is like a block based, uh, dsl. So they added a bunch of stuff into the swift language. Basically when this was going to come out, they didn't say Swift UI was coming out cuz Swift UI is a Apple thing. But you know, swift is a public thing. So Apple was like putting all of. Tools into the language that would like, make it easier to do this kind of a sort of ruby style sort of DSL type thing, um, into the language. And people are like, that's interesting. I wonder what that's for. Right. And then, um, and then they, you know, came out with this framework, uh, called Swift ui. And it, I think what I like about it is that, um, you know, when you do things in this very declarative way, like. What it lets me do is kind of get in there and like make a mess. You know, just sort of write all the code I need to write, but then let, but then decompose it very easily. So, you know, break things down into little component views.

Joel:

Mm-hmm.

Collin:

Write everything in line. Um, you know, kind of like you might in flex right? Or something, uh, you know, you just have all your blocks sort of nested or something, and then I can just pull out the ones, you know, make that its own view and, you know, send messages to it or whatever. And they're all, uh, and they're all value types in Swift UI as opposed to reference types. And that is, What am I trying to say? What I'm trying to say is Swift UI is able to compute everything about your layout at uh, You know, while you're working on it. And so instead of the cycle you would normally have in a native app, which is that you sort of write your code, then you build it, then you run it, then you check it in the simulator or on a device or something, you just, uh, you can just see it update live, which probably doesn't sound that amazing if you're like a web developer because you know, like you get that ac you actually get live, uh, refresh, um, pretty easily without having to have that build cycle. But if you're not used to that, it's pretty cool.

Joel:

I, I imagine especially if the, if the build cycle is quite a long process, how, how long would that normally take?

Collin:

Oh, it can really depend. Um, you know, if it's a big app, it can be minutes. Um, if it's a really big app, it could be longer. Um, if it's a small app, you know, most apps are pretty small. Uh, and those, you know, maybe 30 seconds would be normal.

Joel:

you don't really wanna wait even. a few seconds between making a visual change and seeing what it looks like. I feel.

Collin:

Yeah, essentially that's the thing is normally you, you have to make the change and then you have to build it and wait, and, you know, it's, it's a whole thing. Um, so that's been really interesting and it's really cool how, uh, you know, coming into this sort of new, fresh kind of framework, you know, it's been a couple years now, but this is. This is one of the times where I've really gotten to dig into it and get like, good at it. I decided to actually go through Apples tool tutorial where they like teach you how the thing, instead of thinking I could just wing it. And, um, and doing that. It's really interesting to me how I think, I don't, I don't know if you've ever heard this or seen this, but I think there's a perception with some people that you have to kind of specialize in something. Like one thing, like if you, if you were gonna do swift. You know, iOS stuff, like you have to really go deep on that to learn it. And then like, you know, if you went and spent time learning something like Ruby on Rails, that would be, uh, you know, that that would take away time that you could have been going deeper on the thing that you also do. Right. And my experience is that, uh, is that Ruby and Rails has given me such like a different perspective. Than I normally had before that. It's made me a way better Swift developer actually, which is really neat. Um, just cuz like the way I think about structuring things and all of that is, is much different. And uh, you know, and testing, you know, testing is much more pervasive in Ruby land. And so that's all been really, uh, really interesting to me that actually learning, the more you learn, it actually informs the things you already know more. So, which is really cool. I think.

Joel:

Yeah, that, that makes a lot of sense. I, I think that, uh, I've definitely got a lot of value out of reading books about different programming languages. For example, um, I've read a bunch of books on. The Kotlin programming language, and I've never actually written any Kotlin, but I've read a bunch of books on Kotlin and it's just like to kind of get a feel for a different way of thinking about programming. Kotlin is kind of. um, I dunno what you'd technically call it, but it's like half functional, half object oriented. And also it's an interesting project because they're trying to make it kind of backward compatible with, um, Java, but also like layering on these new features. And so I found that like learning that language and like the process of them making something work with Java and just like completely different ways of thinking. Programming through the functional aspects of it. It's just made me a better programmer in Ruby. They also have like entirely different features like Enums, for example, which Ruby doesn't have, and I felt that Ruby was missing. So yeah, it's, it's super interesting that I don't know. Yeah, i I com I completely agree with you that actually learning different things can help you go deeper on something that you feel like you already know pretty well.

Collin:

Yeah. And Kotlin must have been in, was that your. was Kotlin your first experience with a, uh, with a more strongly typed language then?

Joel:

It wasn't my first experience. I first experienced that with Crystal, I think, and I actually did write a bit of Crystal. But, um, yeah, that was one of the reasons why I picked Kotlin as this language to just kind of like, I didn't, I, I've never written a line of Kotlin, but I've. I have read, I think three books on it, and it's just like familiarizing myself with a different language, um, entirely for the purpose of like, this is just a different way to think about things.

Collin:

Yeah. And it, it is interesting because you, uh, you know, when you jump between the different things, there's definitely things in Ruby where, like you were saying, like Enums, uh, Swift and Kotlin are very similar, right? So I'm just gonna say they're the same They're, I think they have a lot of the same features, uh, like, you know, rich Enums where you can like, you know, uh, do a lot with those types, you know, like add methods to them and things like that is very useful and it's a really cool feature. And you know, you don't really have that exactly in Ruby, you know, Ruby's different. Um, but the trade. uh, is that, you know, when you add strong typing and you add like a bunch more data types and things like that, you know, there's like a lot of complexity, right? Like a language such as Swift or Kotlin is like, It's a pretty complicated, like swift is a pretty complicated language actually. There's a lot in there, uh, to learn if you were coming into it fresh. Um, and you know, Ruby does too, but I think it, there is less to remember starting out anyway, like you go deep with it. But like there's less sort of discreet concepts I think you need to have in your head in order to go deeper with it. And so that's sort of a trade off.

Joel:

Yeah, that that's true. I found it was so helpful to learn about a language with a strong type system and learn almost like cuz, cuz Ruby does have types. You don't declare the types, but it, it does have types when it's running and just having like language, uh, and these concepts like generics and co variants and contra variants and things like that. Um, From Kotlin has just helped me kind of have a different model in my brain for how I think about Ruby, if that makes sense. Even though like I'm not declaring types, I'm still always thinking about like, what type does this return? Um, what is the interface of this? Like that kind of thing. And, and a lot of that I would say is actually comes from the stuff I've read about Ruby and other functional programming languages and other typed, uh, type safe programming languages.

Collin:

Yeah, I think that absolutely makes sense and I'll, I'll give you an example though of. A place where, it's kind of funny, when I first started doing Ruby, you know, if you have duck types, right? Where you have different, you have a class and it might, you know, they may share some methods or whatever. Um, so you can use them in the same sort of context without, uh, you know, them being actually the same type. Right? Um, Like if it walks, if it quacks like a duck, it's a duck. So like this object is a duck that is very different in a strongly typed language. Because in order to do that, you have to declare some kind of an interface to say like, this is the interface that is the shared thing for my duck type or whatever. Right? Like, so in in Swift we'd call that a protocol in Java or Kotlin, maybe even, it's called like an just called an interface. But that, you know, you were saying like these are the methods that are in that thing, right?

Joel:

Yes.

Collin:

uh, because whatever you do, the compiler has to be able to reason about it, has to be able to make sense of it. And so if you don't have that, it, it just, it just doesn't work. It says, I don't, you know, this type is not this other type. And so if you don't have a way to say no, they're actually this other third thing and like generics are part of this and everything, the, that's, there's a lot of complexity there that, that gets added. Right.

Joel:

Yeah. Definit.

Collin:

When I first came to Ruby and I was learning about duct types, I'm like, wait, you just wait, you just call the method. The same thing. Like what? Like how would you, how, how, how does that possibly work? Right? I was like, That didn't, that did not compute in my brain at all. I was like, you just call them the same thing. And I guess you just know to do that. Like maybe you add a comment or something. Um, because in Swift I was always so used to, you know, declaring a formal interface that is like a thing. And now the funny thing is when I go back to Swift and I want to do something like a duct type, right? Now I'm like, why do I have to type this? Like, I just like the physical, like I have to type this thing out. I'm like, you're the computer. You figure it out. You know? So it's kind of going back and forth. Uh, it, it, it's, um, you know, you end up thinking about things in slightly different ways, and I sort of see the advantage of both because I think that a lot of times, you know, different languages are useful for different things. Like if you are. The, the ways that something like that might cause a failure in like a lot of Ruby type languages. Maybe a lot of places where languages like Ruby are used. Maybe the stakes are a little bit different. Like maybe it's okay if like a request fails or something if that happened, where in a native app that would just result in your whole app crashing to like, you know, the home screen. And so that would not really be ideal. Um, you know, and so you use different languages for different things. That's, that, that makes sense to me. But it's, it's, it is interesting how when I first went to Ruby, I thought, I'm like, I'm like, it is so wild west. Like you just type thing, you know, you just name them the same thing. And then going back to Swift, I was like, now I'm like, I kind of wish it worked like Ruby a little bit.

Joel:

Yeah, there, there are definitely advantages. I really. I really like the fact that in Kotlin, uh, I, I believe this is true of Kotlin. It's been a while since I read these books. Um, but once, once you declare, uh, an interface, you specify abstract methods, and when you say that your like concrete class implements that interface, then the compiler's gonna actually help. Implement that interface by saying like, Hey, you haven't implemented this method. You need to do that. And I think that that could be very helpful because it's kind of like documentation. And in, um, in Ruby, we typically will just like define a method that does nothing. And what most people do is they'll, they'll, um, raise a, um, what is it? Um, no method error or something like that. It's not that one. Um,

Collin:

They will fail.

Joel:

Yeah. But, but like, it won't actually do that when you inherit from that, like when you include that mix in, um, it will only do that when you try to use that method, which is kind of, uh, you know, it has its advantages, flexibility, et cetera, but it has its disadvantages as well. Um, but another thing from Kotlin that I found very interesting is, uh, method overloading, which is where you can define multiple method. with the same name. Uh, but they take different arguments or arguments of different types. So they can either take different arguments or, or arguments of different types and they can do different things based on that. Uh, and this is something that I found I am really wishing that we had in Ruby, and I think you could implement it using essentially the pattern matching semantics. Um, so an example of where I wanted to use this recently is, In Flex, you can define Formatters for objects that. So like normal objects from your, from your application, like you might have a date object or a money object or something like that. And, uh, I wanted to make an interface where you could define a formatter for each object type. So if I wanna say, like, if I have, if I'm trying to return some money, obviously I don't want you to just. Call, uh, money dot twos, like, I mean, maybe I could implement that. Um, and, and like we talked about before, the duct type pattern, you could use that pattern to do this, but um, I wanted to have the ability to say like, I'm defining a formatter for this type and I want it to do this thing. And then I'm defining a formatter for this other type, and I want it to do this other thing. And if you have the ability to do method overloading, you could say that the interface is, you define the format method and you specify in. Uh, the parameter list for that method, the type of the thing that you're matching against, then you could do that. In theory, Ruby could support this, like, I think Elixir does this through the pattern matching semantics. So you'd say like, object and then equals grade, uh, equals less than is it or equals greater than, and then the type that you wanna match against. Yeah. That, that kind of thing. I think like seeing what other people are doing, uh, in different languages is. Kind of opens your mind to, well, maybe, maybe Ruby could be different. Um, maybe there are features that I can build in Ruby that I can do with just like meta programming, uh, to make some, like Enums is a good example of this. Um, I have an Enums library or like, maybe it's something that could be a feature of Ruby and maybe, maybe should be pitched, but.

Collin:

Yeah, absolutely. And I think, you know, the thing is in more weekly type languages, like Ruby, the cool thing is you can just kind of do whatever right. Kind of do, uh, you know, the, you, you don't have a com. You're never doing anything to do what I would call, like, make the compiler happy, right? You are just, you write your code and you end up writing a lot of tests and things because, you know, you don't, the compiler is sort of, uh, you know, it's sort of a part of your testing, right? Um, so there are a lot of things you write tests for in Ruby that like you wouldn't write tests for, uh, in a compiled language cuz the compiler would just catch those. And I really like that in Ruby. It's sort of dangerous in that I can just do whatever I want and it never really gets in my way. And I think that's why a lot of people like it because it is a language, you know, it's optimized for programmer happiness they say. I think that shows, because there's a language that really tries to never get in your way. Right? You can just sort of go, but a disadvantage of that is, is that in a language like Swift or Kotlin, you were mentioning how. You know, you declared, um, like an interface and then the compiler was able to say like, Hey, do you want me to insert those methods for you? Like, you know, what's going on here? Whatever. Right. Um, like the tooling was able to, to see that and things like auto complete in a language like that tend to be so much better. I find, because the, you know, the system can, it can look at all the types and it can reason about everything and it can. You know, uh, do completion. Where in Ruby, you know, you can like, create a whole new method based on a string or like, nothing's ever going to figure that out, right? That's not, um, you know, and so auto complete, it's just, it's never gonna be as easy to have it at the same level of quality. But, you know, that's just another trade off. Everything, everything is trade offs, I guess, is, is, uh, is, is what programmers.

Joel:

There. There are some really great ideas. Like one of the things I was reading about and one of these books was this idea of like always having a type for something. So I think an example was, If I'm passing around a user id, that should be a user ID object. It shouldn't be an integer. It should be a user ID object because that way it can't ever accidentally like methods that are expecting a user ID can never be accidentally given the wrong integer. They're always given something that is explicitly a user ID object, and that kind of. I don't know. I think there's something to it, and I think you can, you can go over the top, but there's something to like that kind of explicitness. And I think in Ruby there are ways that we can use, um, things like dry types, uh, is a, is a good example. Which is a library that allows you to specify kind of typed interfaces for initializers. So it, it provides macros that will generate your initializer for you, and the initializer will check the types of the things that are coming in based on. This like DSL for dry types. I think that's a really interesting idea, and it's like instead of typing everything, you're just typing specific INITIALIZER interfaces, which gives you a lot of the benefits while also like not actually kind of changing the language in a way that restricts you at all.

Collin:

Dry types is the same, it's the same people behind hanmi, right? Like those are, that's just the same folks I. Uh, so they, they, they seemed really, seems like a, a real smart group. I'm really, uh, I'm really interested in Hak. I want to, I want to keep experimenting with it. The thing that makes me wonder is have you ever played with any of the like, um, what's it called, like RBS or sorbet or any of this stuff, any of the adding types to ruby kind of things.

Joel:

I have, I, I used Sobey before and I really don't like it. Um, I think that it's like got some really great intentions and some really great people working on it, but I just can't, I just can't look at that dsl. The, the sig, um, the way that you, that you use it is you call this sig method before every method that you define and you say like, what is it? Like paras and then QAN arguments and then dot returns and it's just, So ugly. I, I wish that there was some kind of like, maybe comment semantics or something. I don't know. I just, I just can't, I can't look at it. And I, I know that's like a really whimsical, ridiculous reason to not use it. But I don't know, for, for me, Ruby is a really beautiful language and I love like writing Ruby and looking at Ruby and, and reading Ruby, and it's just one of those things. I don't know. It's, I just can't get along with it. And I've tried, uh, but I'm more excited about the standard, uh, types, what is it, rbs I think that's being worked on, which is where you actually have really nice semantics for defining signatures for your methods that are in separate files. And that, that's really interesting to me. It's kind of awkward having to maintain two different files, but I think it's better than. Having like horrible semantics in the same file. That's kind of kind of exciting. I don't know if they're planning on doing like wiring that up with a type checker. I guess someone could build a type checker around it, which might be useful, but at the very least it, it helps with documentation.

Collin:

Yeah, so I think that the sorbet tools will, uh, the same ones that check your types will also do the same thing with rbs. So you can use the same tools to do your type check. King. And also I haven't looked into this a lot inside of, uh, like VS code or anything, but I know that in RubyMine they have really good support for RBS and also, uh, sorbet for just like, you know, doing what you just said of, uh, it will give you a warning if you try and like if you said this is an hint and you try and pass it a string, like it will, it will pop up a warning in that, in that id, which is really cool. I don't know, I'm conflicted. I feel like when I, you know, was coming to Ruby and I was newer with it, that it was very appealing to me because it felt like it could give me a lot of like the safety that I'm used to coming from, uh, you know, something like Swift. And as I get more into it, um, I think a lot of it could be just that the tooling isn't really there. Is part of it, like you were saying? Uh, it's, it's a lot of maintenance. I found when I tried to experiment with this, uh, cuz you know, you have to, RBS is not like an annotation for Ruby, right? Like it's a, it is just a whole, it, it's its own language, which is to say what, you know, to declare what your Ruby objects types are like. It's a, it's a, it's like a sister language that goes next to it and I don't know, I. I like that it could, you know, it has the potential of like helping with auto complete and things like that, but also, I don't know. I kind of fell off of the idea of trying to actually add this in. It just seemed like a lot of work and not as much benefit as I wanted it to be. Although I kind of feel like if I wanted all of those things, you know, like maybe I would look into something like Crystal or something, you know, or like Swift on the web or you know, if I wanted to get all the strongly type stuff, maybe if I'm gonna have to write all of that, maybe I would just look into a language where that's like a part of it, because it's going to probably be a lot cleaner.

Joel:

I, I think the most value comes from documentation, like being able to, like, if your editor knows what context you're in, when you start typing, it can auto complete the methods that you might wanna call and it can provide documentation for those methods. Like this method takes these arguments. and they should be of these types and this is what they do. All of that stuff though, you can do using, uh, yard documentation and actually that's what Solo Graph uses and I believe that's what RubyMine uses at the moment. I dunno if they're also doing rbs, uh, or like, um, sobe at the same time.

Collin:

That's actually the one I've done the most of probably is just putting in, uh, yard dock comments. Um, because like you said, that's actually, uh, Ruby mind supports all of them. I think so. It just, if you do RBS or sorbet or yard dock, it will just any, they all have the same result in, um, in Ruby Mine. And I think, I think the comments one is probably my, the one I've done the. Yeah, and it's also, it also does make your, uh, solar graph stuff work better, and it's not quite as junky, maybe as, as adding the, uh, the sorbet code.

Joel:

I'm just looking at defining, uh, yard documentation for all of the methods in Flex and Flex Rails at the moment, which is interesting, particularly because what I'm working on on Flex Rails at the moment is, um, basically building adapters for almost every single rails, uh, helper. So, There is a ton of helpers in rails. A lot of them, like they all work in different ways. Some of them return. Strings, uh, of like html that you're expected to output onto the page using like the output, um, er b tags, some of them return values, um, like true or false or an object or something like that. You are meant to like do something with, and in fact, like I've, I've worked out, there are, there are like five different types there. These output helpers, there's output helpers that have a capture block. There's value helpers, there's value helpers with a capture block. There's um, and then there's this extra type, which is kind of interesting, which is, um, a builder yielding helper. So there are some helpers like Form With is one example. Uh, form four is another example label. Uh, tag, they all yield builders, so you could say like form with do f f dot text field. Um, and the f is this yielded form builder. And what's interesting about this in flex is when form with needs to output onto the page immediately it, it can't return something in flex. It doesn't make sense for it to do that. Um, and so when the form builder is yield, all of the output methods on that also should immediately output something onto the page, right? So if I call like F dot text field, I don't want that to return a string because it's not gonna go anywhere. I actually need that text field to be output. So I've been building like these, and this is actually the first time I've ever found a practical use for the decorator pattern. I've been building these objects. Kind of like wrap the builder objects and they have like a specialized interface that that captures the, the return value and puts it. Like pushes it onto the buffer and then there's like this special list of methods that actually are meant to return a value rather than output something. So that's been a really interesting project and I've got almost all of the helpers working now. There's, there's a handful of helpers that I just need to tweak a bit bit further, but this kind of led me. The path of, uh, going, going back to yard dogs. Um, when you include these helper modules, the, they're like, they're not the, the original helpers. They're my adapters for them. There's no documentation at all in terms of like vs. Code auto complete. So I'm looking at like defining. Kind of trying to use yard to define all of these helpers, documentation and yeah, just trying to figure out if there's a way to automate, like pulling the documentation from re the Rails API and bringing it over. But actually the Rails API documentation is pretty poor. Um, they don't use yard, so they don't define parameters.

Collin:

Yeah. They just use like RDoc.

Joel:

Yeah. They just use R Doc. They don't define parameters and in fact, the, the signatures themselves, because they don't use ruby keyword arguments, they also aren't very helpful. Like you cannot tell just by looking at the documentation whether or not, like what you can't tell what options of particular helper method takes. It just says like that. It, it, it just says like, options is the last, is the last argument, right? And that's a hash, but the, but you don't know what, what keys you're expecting options to receive. So you have to actually look at the examples, and that's the only place where you can tell like, oh, this is, these are the options that are valid to be passed in there. So it's, it's kind of an opportunity actually. and because, because I'm using yard, like these are, these are dynamically defined methods in terms of like the flex adapter for the helpers. So you have to use in yard. It's like, uh, the method, uh, declaration, which is where you say, um, you create a comment and you say at exclamation mark method, and then you can type the, the method signature as if you were like defining it. But, um, because I'm doing that, it's actually an opportunity. Kind of specify these helper methods with keyword word arguments instead of just taking a hash on the end. Because it's the same semantics when you use the method, you can pass in keyword word arguments because Ruby's just gonna take the last keyword word arguments and pass them in as a hash. So yeah, I'm tr I'm kind of like, I don't know if I want to open this can of worms cuz there's something like 140 or 150 helper methods to go through. I am pretty tempted to document them all. I don't know what you think about that,

Collin:

Yeah, that's that. So if I'm understanding, you basically have to go through all of these 140 things and. Fix whatever impedance mismatched they would have with Flex to make sure that they, you can respond to them and you can use them within Flex. That sounds like a ton of work. Um, but everything you said about it makes total sense. That all sounds that everything you said sounds great. It just sounds like a lot of work.

Joel:

Once I figured out that there are, there are just these, these five types of, um, of like helper method that you can have. I've been able to define macros. That define the methods. So like I have a macro called, uh, define builder, yielding helper and it takes a method name and a builder, and the builder is basically one of my decorators. And then it will automatically like generate the method based on that method name. Um, you know, define, it defines the method, um, captures the. It wraps whatever is yielded from cooling the method in my decorator and then yields that and then like checks the type of the output, makes sure it's an active support, safe buffer, and then pushes it onto the buffer at the end. So actually, That has not been too difficult because it's, it's just been a case of like going through all the methods and figuring out which ones take a block that yields a builder, and then just using this macro for each of those, those helpers. And of course, like defining, defining the decorators themselves. But there aren't that many. There's, there's literally only, there's a form builder, a label builder, a radio button builder, and a label builder, and that's it. Oh, and a tag builder.

Collin:

It's funny, I had two thoughts when you were talking about it, which was when you were talking about the hashes and you know, figuring out what types it's actually using and what's going on. There. Um, I was thinking that, uh, an an enum of the type that you get in Swift or Kotlin, uh, you know, to declare like what the keys are and like, you know, associate types of things would make that very, would make, would be really nice. There, uh, was one thing I was thinking about.

Joel:

I mean, or, or just using keyword arguments, right?

Collin:

Yeah. Or just using keyword arguments, but that, that was a place where I was thinking like, oh, something from that other world would've been. Like nice to have in this world, you know? Or you know, like you said, keyboard arguments are also a choice for that. I was just trying to relate it back to what we were talking about before. And the other thing I thought though was you were saying, you're like, yeah, and I just generate all these methods like at runtime or whatever, uh, and that, that is something you absolutely like could not do if you were, uh, in that other, you know, uh, very strict kind of world, right. Of just being like, I'm just. Generate a bunch of methods off of like a, you know, a string. I'll say what they're called or whatever. Um, you know, you can do crazy stuff like

Joel:

you not have macros in in swift?

Collin:

Uh, they're adding something for that. Yeah. They, they are adding some, they're adding macro support that's coming, but, um, But the thing about just like declaring like, you know, like declaring a, a method at runtime or whatever, you know, based on like, I just want to be called this. And, uh, you know, you can't do that without dynamic run time. Right there, there, which doesn't exist, uh, in the same way in some of these other languages. So that, that was really, uh, interesting to me. Like for example, if you wanted to, um, there might be newer techniques to get around. That I'm forgetting, cuz you know, I'm not always a hundred percent up to date on all the new stuff. But, uh, like for example, in declaring like a DSL from, let's say for example, you wanted to have a DSL which mapped, you know, Ruby to html, you know, imagine such a thing, who would do it? But, uh, you know, in, in Ruby you could, you can have like a method, not you can override like a method not found thing. And you can, you can kind of just. Make sense of it at, at runtime, where if you were doing that in a language like Swift, you would actually have to declare each of those things. So like each HTML tag, you would actually have to declare that.

Joel:

So in Flex we actually, we actually do declare them.

Collin:

I, I was just saying as an example, but yeah, obviously, you know, you could also declare them, but I meant like if you wanted to have a fallback, you know, if you were, if you were declaring something where you wanted to say, and the fallback is just like output this as text or whatever, but don't crash, right? You would, that wouldn't really be possible in the

Joel:

I wonder if the decorated pattern that I'm using, uh, would be possible in Swift. I, I have a feeling it probably wouldn't. The decorator pattern is basically, uh, you just have an object or you, you have a class that takes, as it as its initializer argument, it takes an object to decorate, and then that class defines method missing, and it basically just calls the same method on the object. And this class inherits from basic object, so it doesn't have, it basically has only a very, very small. Number of methods on it in the first place. So basically everything that you send to this, um, this object is, it's as if you're sending it to the underlying object that you initialized it with. You can kind of like wrap an object in a different object and everything is forwarded by default. And then you get the ability to actually. A specific method on the object that can override one of the, the methods on the underlying object. And it can essentially call super by like, calling that method on the underlying object, but it can do things to it so it could like return something else based on that. And so what what I'm doing is, is using this pattern, there's basically a method missing that delegates to the underlying object, but it wraps that delegation in a capture block so that it. Kind of like capture the output and then output it, or actually that, that's how, that's how the unbuffered one works. How, how The one, the one that I'm working on today works is it, it captures the return value and instead of returning it, it pushes it onto the buffer, assuming it's, uh, a safe, uh, return value.

Collin:

Yeah, you definitely couldn't do that in exactly the same way. This isn't really not a TA implementing decorator pattern in SWIFT is not something I'm like an expert on. So, uh, I'm gonna leave this as a homework assignment for myself to research a little bit more and see what the equivalent would be. I think you could get some version of an equivalent to what you're talking about, but yeah, it would be. right? It involve, you know, you can, uh, it probably involve like generics and things like that. You know, you can have like a result type and then say like, this is the type that this is wrapping and it's, it's, it be, it becomes complicated. Right. Um, I was trying to follow everything you said, but there's a lot there. So to go back and verse myself in that a little bit more. So I think this is all really interesting. It seems like we both had really good experiences with you. Different languages and learning, you know, different ways to sort of approach the same problem taking, uh, you know, taking cue from other languages. So I, I don't know, um, definitely I think that's kind of an evergreen topic that we'll probably come back to over time. But, uh, do you have any, any final thoughts about that?

Joel:

Uh, no, not really.

Collin:

I have a final question I'm gonna throw at you, which is, do you have any languages that you are interested in kind of looking into that you haven't yet? Like what's, if you were going to look into something next, what would it be?

Joel:

that's a great question. Um, I think I'm kind of looking into, um, rust at the moment, which is, and the reason I'm looking into that is I want to have as like something in my toolbox, the ability or tool belt, um, the ability to, um, to like build a, um, a kind of like extension for Ruby. For parts that are possibly too slow in Ruby, uh, and I think Rust is a pretty good option for that. Um, another language I'm pretty interested in is Zig, uh, which also looks great.

Collin:

I think those are both great choices. Uh, I, I keep thinking maybe I'll look into rust. I feel like it, um, that's, you know, it's, it's whole thing is like, it's very strict. So like you are, when I was talking about making the compiler happy, I think. Rust people, uh, rusts will say they're more like, no, it's more like you're having a conversation with a compiler cause it's like guiding you, but that at the end you have code which is like very safe and they, people who like it, like love that. I think the language I'm interested in next is maybe elixir, I'm thinking. Cause I think I wanna learn something more kind of, uh, that goes further in the functional direction so I can really. Internalize more of that stuff, you know, because in, in languages like Ruby and Swift and things, um, in the languages I, I already use a lot, they all kind of have like, you know, functional is a part of it, but also it's not, it's not like the overarching thing. So I think it would be interesting to me to work with a language which was, uh, more purely that. So, alright, so I'm gonna learn Elixir this week and you're gonna learn rust, uh, and

Joel:

I'm gonna keep working on documenting these

Collin:

I think you should keep working on documenting your thing. Yeah. Um, so, uh, this is great. Thanks for, uh, doing this with me again, Joel. And I think we will probably be back in two

Joel:

Yeah. Hopefully I'll have internet by.

Collin:

Hopefully you will. Well, uh, thanks everybody and, uh, talk to you then.

Podcasts we love