During Apple’s WWDC 2015, we were very happy to host a panel of leading voices from the Swift community. Reflecting on Apple’s latest announcements, including Swift 2.0 and Xcode 7, we look back on the last year, and we look ahead, to the new opportunities & challenges we face as a community. Many things were discussed, with sparks of insight, humor, and affection in turn: the balance between polish and new features, pain points old and new, living with different versions of Swift, combining functional and imperative approaches, Apple’s new emphasis on testing, and how an open source Swift will change the landscape, and the community, in the coming year.
You can read a full edited transcript below.
Chris Eidhof: Hey, I’m Chris, I make objc.io, I co-wrote a book called Functional Programming in Swift, and I’m writing another book on Swift. I wrote my first Swift app in the last month, called Scenery.
Ayaka Nonaka: I’m on the Venmo iOS team. We started writing a lot of Swift in our codebase, everything new that we add is in Swift, and we test Objective-C in Swift.
Ash Furrow: I work at Artsy. We wrote an application in Swift, called Eidolon. It’s completely open source, if you’d like to check out the code, it’s on GitHub. I also do some writing. I just released a book on Swift, this Sunday [audience cheers].
Nate Cook: Thanks so much for having us all here, this is a really great opportunity to have a community all together. I’m managing editor of NSHipster, and I created SwiftDoc.org, which hopefully you’re all finding useful. SwiftDoc was just updated with the 2.0 Standard Library. Apple has the actual documentation out there now, but there’s going to be some changes and opportunities with SwiftDoc coming up, so stay tuned.
Natasha Murashev: I’ve been working with Swift at Capitol One. Everything I learn, I write on my blog. I also started This Week in Swift, a newsletter to keep track of all the awesome stuff that comes out.
Jeff Hui: I previously was at Pivotal Labs, but now I’m working at a startup called Maven. Not the Java thing [audience laughs]. It’s written in Clojure. On my off time, I work on Quick and Nimble, both testing frameworks, as well as Fox.
How would you characterize the last year of Swift, and how has the language and the community evolved in that very short time?
Chris: That’s a big question. People who have been doing Objective-C for a really, really long time, I think they were a very interesting group to look at, to see their reactions. Some people were really excited, and some people were not. Now with Swift 2, things changed again. A lot of people are now more excited, and we’ve got a lot of new people and new ideas coming. This is what I think is really cool. We have all these people from Ruby, from Haskell, from all kinds of communities coming in, and there’s been a really positive atmosphere around Swift. There have been some haters, sure, but you get them with every new thing. Mainly, people are excited, and building new stuff. There are many new opportunities.
Ash: There are other people from other communities coming in, and there are people in this community who see Swift as something that can let us do new things, either things we couldn’t do in Objective-C, or that Objective-C made it very hard to do. I see this collaboration and this acknowledgment, finally, from iOS and Mac developers that, when it comes to software developers in other communities we have more in common than not. At the community level, I really think this can be attributed to Swift.
Nate: It’s seems clear that there was a lot of pent-up demand for a language other than Objective-C, to work with the devices that we love so much. It’s been fascinating to see the new people that have come, who have seen this new language and are getting excited about writing for the iPhone, or the iPad. Just seeing all that explosion of new interest has been really fascinating, and really exciting, for the whole community.
Ash: One of our Android developers recently left to do his own thing. One day I saw him check in on Swarm to an Apple Store. I was like, “Why are you checking into the Apple Store?”. He attached a photo of an iPhone, which he had bought. Then the other week, I realized that he’s actually a Swift developer now, writing Swift full-time. So even people from the Android community are joining the Swift community.
Jeff: I think bridging to other languages to get new inspiration and ideas helps advance the whole field of software engineering. It doesn’t have to be Swift specifically, but the fact that it’s a relatively young language means that the community is much more adventurous.
Get more development news like this
Nate: One more observation; it feels like we’ve all had a shared experience over the last year. When Swift was announced, we were all beginners, we all got to learn it at the same time, and we helped each other out. To discover a language at the same time is a really unique situation in programming.
Do you feel that Swift has struck the right balance between polish and new features with the announcement of Swift 2?
Ash: Yes. I watched the State of the Union presentation, and, if I remember, Chris Lattner said, “We’re finally doing it the way we should have been doing it all along.” There was a really cool recognition that Swift 1.0 was not perfect, that they know it, and that they’re working on improving it. I really appreciated the honesty. The transition from 1.2 to 2.0, I think, is going to be a lot less painful than the transition from 1.1 to 1.2.
Natasha: When listening to all the announcements, it felt like Christmas. For every announcement, I was thinking, yes, I do need this. I was like clapping at every single one. It really felt like these were things we wanted, or sometimes things we didn’t even know we needed. Wow, they really listened to us.
Ayaka: Even the Objective-C stuff that was added, like generics and nullability, I think those will be huge for Swift as well. You can write lots and lots of Swift, and have lots and lots of classes and methods in Swift, but at the end of the day unless you started a fresh project with all Swift, you’re going to have to tie it together to all of your existing Objective-C code at some point. And that tends to be one of the most painful parts about Swift development.
Chris: I studied compiler engineering, so I always think I know better. And I have strong opinions on the functional stuff. Every time the Swift team comes out with a new release, it’s always very different from the thing I would do. Almost every time, it’s also way better than I could imagine. I think this is a big thing; these people, they really think hard about these features, and they think about what we need. There’s all these features that they build that actually make our lives easier. And I have the feeling that it’s not really like compiler writers trying to prove cool stuff, they’re actually looking at what people are doing and making our lives better.
JP: An example is
guard. When Swift introduced optional binding, or
if let, there were so many people that wanted the opposite — they wanted
if not let, or they wanted to put an exclamation mark in front. And that could have worked. The Swift team could have caved in to the pressure and said, all right, the people have asked for X, so we’ll give them exactly that! I’m really thankful that they didn’t, in fact, they came up with a much nicer way of doing it.
In the last year, what have been some of the pain points that you have experienced with Swift, and how do you think those will change in the next year? What will be the paint points moving forward?
Jeff: The compiler keeps crashing [audience laughs]. More importantly, I think library support. Libraries that have mixed languages seem to change in subtle ways with each Swift version, which as a library maintainer is a definite sore point. You can try to hack around it to build apps, but if someone else uses my library as a dependency of their library, then this doesn’t work. The library infrastructure is still relatively new, and you hit a lot of roadblocks compared to regular app development.
Ash: Yeah, I think it’s a fairly unique thing. Swift didn’t follow semantic versioning; 1.1 to 1.2 had breaking changes, which isn’t something you normally see. The transition from one to the other was very painful, because if you depend on other libraries, they also have to support it. And if you’re not ready to upgrade yet, but there’s a bug fix in the library, that’s also painful. My hope is that in the next year we’ll see that pain recede. These are real problems, and they cause a lot of frustration, but I think that they’re temporary, or ephemeral at least. They’re not worth putting a lot of effort into solving, because hopefully next year Swift 3 won’t have breaking changes, it’ll just have new things.
Nate: I think the biggest challenge that I face, is that Xcode is working with a moving target, and therefore it’s not terribly stable to work with. It’s a challenge for developing with it, and it’s a challenge for recommending Swift as a great new technology for people to move to. As bad as it is for me when I’m researching, writing and trying to get playgrounds together with an Xcode that’s crashing every five minutes, it’s even worse if somebody’s production code is in that state and they’re trying to work around it. I think that’s one of the biggest challenges that Swift is facing right now, and because they’re actively trying to improve the language, and trying to add new features to Xcode, that may not settle down for a while.
JP: It’s great that Apple released Swift relatively early on, to gauge developer response and actually interact with the community; this level of communication with the outside world is something that Apple have never done for any other technology.
Ash: I’ve never had a crash in a production application caused by Swift. It’s only the tooling, which is actually kind of promising, though I know that it’s also really frustrating. It’s frustrating for me, but from my user’s perspective it doesn’t matter, and that’s good.
Ayaka: Sometimes when I’m working on something simple, it just doesn’t work. Obviously I blame myself, because I’m learning, and I probably did something stupid. You just go down these crazy rabbit holes, you try to make a small test case, and then that doesn’t work either. So you tweet out, “Hey, does anyone have any problems with this thing?” And they’re like, “Yep, that’s a bug, I already filed a Radar.” I have a lot of those cases that kind of pile up. I think it makes it hard to start learning, because when you’re learning you always blame yourself, but with Swift it could be the language itself, or the compiler, or Xcode.
JP: Swift makes novices of all of us, really.
Chris: I have basically the same moving target problems, but I want to add a positive note. Yes, Swift keeps breaking with every version, but it’s a short pain. Yes, you need to spend a day, and in the worse case multiple days, in the best sometimes just a few minutes, upgrading your code. But there is a long-term benefit because you get all the new features. I think this is something to recognise. And I think with the changes that I made, I never actually had code that all of a sudden stopped working. Sometimes it didn’t compile, but there were no new errors introduced where the compiler produced the wrong results, or stuff like that. Yes, it’s very painful to have to upgrade, but they’re doing a good job with the migration assistant, and communicating the things that you can do. Pain, but also things that alleviate the pain a bit.
Natasha: Yeah, so one issue I find working on a team is that Swift doesn’t have a standard. People have different ideas about how it should look, and then they commit code. We have a pull-request system, so I’ll be looking and I think, “No, that’s not how you do it in Swift”. But then right now there’s no right answer. It’s slightly challenging to have code consistency in a team.
Chris: I think one of the coolest things about Swift is that we now have value types for more than just numbers. We can make structs, then pass them by value, and everything gets copied. This is awesome. Inside these value types you can have reference types. This works, and the references get copied, but it’s not the actual values that get copied. I think as more people start using value types I’m a little bit afraid that this might cause a lot of confusion, because people may not understand how this works. I get bitten by it all the time, and I think I understand how it works. It’s very easy to make mistakes there, and I hope that something will happen to improve it. I think this might scare people away from value types, and prevent them from fully grasping the distinction. I have to add, of course, that this is what makes Swift really powerful. Mike Ash wrote this great article where he re-implemented Array. Array is a struct, it has values semantics, but he implemented it using a pointer, and he implemented copy on write. The fact that you can do this is awesome, and this is the reason why we have mixed value and reference types, I guess. This is the price we need to pay for having that awesomeness.
Should we live with concurrent, stable versions of Swift? Should app developers, or library maintainers, completely cut off support for 1.2 as soon as 2.0 ships?
Ash: I don’t know, it’s this really nebulous thing of like, what are you going to do? Boris Bügling, aka @neonacho wrote a tool called CHSwift. It’s a command line tool that lets you specify which version of Swift you want to use, which is really cool. But it doesn’t address the real problems of migrating and working with these concurrent versions. It’s really frustrating for other reasons. I want to use Xcode 6.3 because it’s better for my Objective-C projects, but in Swift I can’t use it, as I haven’t had time to upgrade to Swift 1.2. My hope is that Apple realizes how ridiculous this is. We really should be moving to a model where we don’t have breaking changes every time, and where it’s okay to run Swift 2 code in a Swift 3 compiler, because it’s backwards-compatible.
Natasha: We have a pretty large codebase, and recently the priority has been to release the app first, so it has stayed in Swift 1.1, because upgrading to 1.2 is not our priority.
Jeff: It’s interesting to look at the Go programming language. In the early days of Go, before they reached 1.0, they actually had a similar period where they were doing a lot of releases. What was interesting is that their migration plan was actually, as they put it, “too good.” Their migrator would automatically migrate the code between versions, which allowed them to break changes every week. Besides fragmenting all the potential libraries out there, it also caused a kind of interesting side effect: a user would just pull in and run the migrator, which would fix the breaking changes. I don’t know how practical that is in Swift, and it’s certainly a lot of work. A simpler approach might be a useful compiler error, there’s obviously a gradient between something that is very pragmatic, or simple, and the auto-migration route.
Swift tries to strike a balance between imperative features and functional approaches. How do you think that balance has shifted with Swift 2?
Chris: I was talking about this yesterday with somebody. We talked about what got him interested in Swift. It’s somebody who manages a really large team, they have Java on one hand, and C++ on the other hand. He told me the Java code works fine, but he gets garbage collection problems, whereas the C++ code crashes. And these people, they do know what they’re doing. So I think it’s very interesting that we now have a language that’s not garbage-collected. All of a sudden we can do all these awesome things. We can write really high-level code, sometimes even with zero cost — like if we wrap C things in a nice way, in the end it’s the same C pointers we’re operating on. I think this balance is really cool, and I think the new features that just arrived are reinforcing that. None of the features are particularly functional, as in Functional Programming, but they’re really functional, as in useful, right? So I think the balance has not shifted much in that sense. We still have a really high-level language that allows us to do low-level programming, and allows us to write really fast code. It really is a systems-level language, but with the possibility of doing more advanced stuff, at higher levels of abstraction.
Ash: The thing that I really liked about Swift, over Objective-C — besides everything [audience laughs] — is that Swift enables you to do functional programming. There are a lot of really interesting things that you can do that you just couldn’t do in Objective-C. It’s really freeing; if you want to write functional Swift, you can. If you want to write imperative Swift, that’s a bad idea [panelists laugh]. Swift lets you do things the way that you think they should be done. If you want to dip your toes into functional programming, you can. You can adopt it slowly, it’s not all or nothing.
Nate: I think one of the things that has been super interesting about working with Swift, and getting to know it over the last year is that Swift has something approaching a clear mission statement. People who are coming from Haskell, or from a pure functional programming background will bang their heads against Swift, and be frustrated that it doesn’t do everything that Haskell does. But it’s deliberately not a functional programming language in the same way. If you go back to the introduction of Swift, this was very clear. “This is the best new functional language” was not something that they said onstage, it wasn’t part of their stated goal. And if you follow Apple engineers on Twitter, you can see they know what they’re talking about with functional languages. What is coming out of Apple is a deliberate decision. In John Siracusa’s review of Yosemite, he talked about how Swift is a very Apple-like language. They have made decisions where at first you think, well, this isn’t perhaps the way I would have done it, but the more you think about it, the more you see the reason behind it. There’s a philosophy behind it, this wasn’t an accidental decision.
Natasha: The nice thing about Swift is that it’s like a ”Choose Your Own Adventure” game right now. You can choose to go all the way, like Chris. Or if you’re working in a big team, and you want the new person to come to the team and be able to read your code, you can choose that path. Apple has taken a really good approach: if you feel good about functional programming, you can take one step at a time, you don’t have to dive right in.
Jeff: I think it’s a really interesting balance that they’ve struck between the imperative and the functional world. Very few languages target that, which I think may put Swift in an interesting position. Most of the time, languages either go completely functional, which forces you to do that full switch, which I have, or they go more towards the system, or the metal. I feel like Swift encompasses the whole gamut, and it allows different teams coming from different perspectives to pick and choose what they want, which I think is super valuable.
Chris: I think there’s been too much focus on the word “functional” [audience laughs]. For me, what I really like is writing programs that are clear, that are safe, and that do what they should do — not being able to make any mistakes myself, and reading code that doesn’t make any obvious mistakes, hopefully. Functional programming, or at least applying some things from functional programming, can be one way to do that, but it’s not the focus of Swift. If they wanted to build a functional language, they would have done it a different way. It’s just that if we want to, we can express ourselves that way. And it is sometimes the same thing as using immutable data, or writing clear code. I think this is what they focus on. This is what I find interesting, and not so much that it’s about functional programming. It’s really about writing safe code that’s easy to read and fast. I think this is what we also should be looking at, and not so much at the functional side. That’s just one way to possibly get there.
Ash: The other thing beyond the functional part is the familiarity. Even if Apple had wanted to make a more “functional” language, whatever that would mean, I believe that the future of Apple as a company depends on Swift being adopted. Objective-C isn’t going to be a competitive language in 10 years. It’s going to be ridiculous. No one’s going to want to write apps in Objective-C in 2025 [audience laughs]. I’m serious, would you want to write your iOS apps in C right now, with no object-oriented programming? No, it’d be ridiculous. Apple needed Swift to be adopted. More than anything, Swift had to be a success, and still has to be a success. I think that a big part of the decisions that Apple made were because developers would be familiar with Swift, developers would feel at home. People who have been writing Objective-C would know how to write Swift out of the box. Maybe that hampered Swift a little bit in terms of reaching its full potential, from the perspective of whatever ideology you might happen to adhere to, or I might happen to adhere to, but it’s still a good business decision.
JP: What I especially liked about the approach that they took was that you could basically just human-translate, almost machine-translate, your Objective-C code. Switch out the square brackets for parentheses, and you could still write it pretty much the very same way. Aside from a few specific features, like some dynamic features of the Objective-C run time, you could just translate the whole thing in one go. After that, you would step back and look at it, and go, ”Well, there is this neat little map function over here, I could use that”, or, “I’m going to grab a filter from here.” It’s like you’re walking down the aisle of a grocery store, picking things up piecemeal. You can choose to ship your app at any point in time, but you kind of get nerd-sniped at the same time too. You go, “Oh maybe I can find things in the other aisle.”
Apple really put an emphasis on testing in Xcode 7. Do you think they’re moving in the right direction? And is there something that you particularly like, or particularly dislike, about their approach?
Natasha: Coming from the pain of last year, I’m very happy with the solution.
Jeff: I’m much happier about the UI testing side, actually. That was a huge pain point, and UI testing is super valuable. On the Testable side, I think they’ve made an interesting trade-off. It’s super useful when you’re testing apps, because you don’t have to make everything public. For libraries, it’s actually less useful. When you’re testing a library, you really should be testing your public API, no one should really care what’s going on internally, unless there’s actually a side effect that can observed through the public API. There is obviously a balance to be made, and I think it’s fair to say that we work more with apps than with libraries, so the balance should probably be in their favor.
JP: I think it’s worth debating here. Correct me if I’m wrong, but it’s essentially comparing white-box testing to black-box testing. It’s not like there is one clear-cut solution for every framework out there, or every app out there, where only black-box testing will do, or only white-box testing will do. Say you have a framework that does something crazy complex. Inside, you have some string manipulation functions that you don’t want to expose in your public API. But maybe it’s worthwhile to just go through these edge cases while you’re testing it. Maybe you want to keep that internal. So do you really feel strongly that they should have kept it as is, with Swift 1.2, where you would have to make something public, because you could only test your public interface?
Jeff: Like I said, strong opinions. But no, I don’t actually say that, I don’t agree that making it impossible is a benefit. Obviously there are always exceptions to every rule.
Ayaka: I have very mixed opinions about the Testable plug. I don’t think we should test private methods. But in the end, it’s all a trade-off. If you make everything public or make it testable, and you test everything, it just makes it harder to change. Even though you’re only changing some internal method, you still need to update your tests. On the other hand, I think having more tests is safer, it just makes you move slower in the end. My idealistic standpoint is that you should only test your public API. If you change your public API, and you change your test, that means you made a breaking change.
Nate: I think the code coverage will be neat. That can add a little bit of gamification to the process, and encourage people who might not otherwise test to start that process. Then, with the Testable thing, I haven’t played with it much, but as far as I could tell, you get to choose. If you want to only test your public API, you leave out
@Testable. If you want to test your internal methods, you add it. You could even add two different sets of tests. So we certainly get to pick and choose, and I think that’ll be really valuable going forward.
Ash: I know Orta has been working on gamifying the CocoaPods CocoaDocs. You’ll be able to see how many people have downloaded your pods, and so on. But they also give you a boost if you test, and they give you a boost in the search rankings if you document your API. And now, we’ll be able to give you a boost, depending on how much you’ve tested your application, and that is really exciting to me.
By the end of 2015, both the compiler and the Swift Standard Library will be open source. It’s an announcement that took a lot of us by surprise. How do you think this is going to impact the community? How will it change the landscape?
Ash: I’m really excited about this, and not necessarily for the implications of it, like running on Linux, running web servers, or running embedded hardware. What I’m really excited about is that Apple rarely acknowledges the community, and now they’re making this contribution to the open source community of a compiler, which brings it up to par with Objective-C, and the run time, which goes above and beyond what they’ve ever really done. That is incredibly exciting, because not only are they acknowledging that the open source community exists, but they’re contributing to it, and asking for feedback. From a company perspective, that was the most exciting implication of the entire keynote.
Nate: I think it’ll be very interesting to see how the community will contribute. Do we go to GitHub and do pull requests? What’s the extent of the involvement? I think the big question mark is, what is Swift like to work with when there’s no Cocoa, when there’s no Foundation, when we don’t have a date class? What are we working with? Is it going to be like Node, where there are a gajillion libraries that we have dependencies? I was at a great talk this morning by Justin Searls, who talked a lot about the pain that all these layers of dependencies and transitive dependencies can cause when we’re trying to build something simple, and have this teetering stack of libraries that we’re standing on top of. So it’s really exciting news, and it’ll be fascinating to see how it plays out. I hope that we can all contribute and be a part of that process.
Chris: I think it’s really awesome. The other day we were wrapping a C library. And now, even if Foundation remains closed source, it’s very easy to wrap all these libraries that exist. There’s so much good stuff out there, specifically on Linux, there is so much good stuff that we can wrap. And it’ll be lots of fun, I think lots of new stuff will happen. I’m really, really excited to be able to write Swift on the server-side soon. This is going to awesome. Imagine writing Swift and deploying it to Heroku, or whatever. This is going to be so cool.
All this said, I have a slight worry. I acknowledge that the Swift team has some experience with open source. These people know exactly what they’re doing. Still I’m a little bit worried that there’s going to be people like me, and some other people in the community, who think they know better, but they don’t, who will eat up the time of the Swift team. But I guess, if there are also good ideas coming out of that, it’s very interesting. If somebody makes a pull request, and it’s actually an awesome feature, then yeah, that’s really cool. So I’m a little bit worried about that, but I think the net result will be positive.
Ash: There used to be this joke, back when the year of Linux on the desktop would be around the corner. Whenever a new piece of hardware came out, you’d be like, oh, does it run Linux? And now it’s going to be, does it run Swift?
I’m really excited to see this sort of adoption of and proliferation of this language. Swift exists independently of Apple, and now it’s going to be even more independent of Apple. Its success is no longer directly tied to Apple’s influence, and that’s really cool.
Jeff: I’m super stoked about it, because once again it shows Apple’s commitment to the language, It’s not like they might change their minds halfway through. They’re going full-board. Like this is the way, this is the future. They’re removing all our excuses: it’s not open source? Check, done.
JP: It’ll be huge. There are so many unknowns. How are they going to be interacting with the community? With WWDC coming around once a year, are they going to hold some features back, and then just dump it in one massive pull request? Are they going to be developing this throughout the year? Looking at what they’ve done with Clang and WebKit, and the other open source things, it seems like it’ll be more the former, while still encouraging and accepting work for the current version from the community.
Chris: I was just wondering, I’m not completely sure, but I do think that probably, if we want to look into this, it means that we’ll all have to learn C++. [audience laughs]
If you had one piece of advice to give, either to the people working on Swift at Apple, or to the community, and the people in this room, how would you advise them to help Swift reach its full potential?
Jeff: Communication. It’s really all-encompassing. A lot of problems get solved just by having open lines of communication. This will keep Swift thriving.
Natasha: I’d say keep an open mind. When you switch from Objective-C to Swift, you still have your Objective-C brain. When approaching Swift, take a clean slate, clear your mind. You’re in Swift world now, start fresh.
Nate: One way to get a feel of what Swift is, and what is Swift-like, is to spend some time reading the Standard Library. There are decisions there that aren’t obvious, and don’t follow from what you’ve seen in other programming languages. The string implementation, in particular. You don’t interact with strings in Swift the same way you interact with them in any other language. When you think about why, and when you read the explanation, you get a clearer sense of how the Swift team is making these decisions. They’re really approaching things from a good perspective. So that’s one thing: spent a lot of time in the header file.
Ash: I’ll echo Jeff, communication is going to be key. There are two things I’m excited about. The first one is how active and responsive the compiler team has been on Twitter. I complained about something, and it turned out one of the engineers follows me, which is really embarrassing because I feel like I insulted him. So he took my ranty tweet, and he filed a Radar for me. Over Twitter, which was just mind-blowing. I’m really excited to see this shift in Apple, because engineers in Apple don’t just go out on Twitter and file Radars for you because they feel like it. There has to be a very strong push from a very high level in the company in order to get that sort of external behavior, and that is really exciting. I’ve never been more excited to work on an Apple platform, because of that.
Ayaka: My advice is, just try it. Even if you’re working in an Objective-C codebase, and you’ve only done a little bit of Swift, you will end up contributing back to the community by building something. Everyone builds different things, and when we build different things, different problems will arise, and different problems will get fixed.
Chris: Maybe one other thing you could do is try to have fun with it. Most people I know that are programmers got into it because it’s so much fun. There are all these new possibilities. Take playgrounds, we can do a lot of awesome stuff with this, and we can share a lot of stuff. All of sudden, if you start writing about Swift, or start creating your new project, you might get noticed.
JP: It’s going to be our language soon, so we better make it our own. I’d like to thank our wonderful speakers. Please give them a great round of applause!
About the content
This content has been published here with the express permission of the author.