Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

May 10, 2008

Scala lift-off: Martin Odersky Keynote

I'm at the Scala lift-off today in San Francisco, an unconference organized by Dave Pollak, author of the lift web framework and frequent hanger-out at the Twitter office (or Twoffice if you will).

Martin Odersky, author of the Scala programming language, is kicking off the day. Martin teaches at EPFL in Switzerland, and has a background in functional languages. Before Scala, he's had a hand in several functional languages on the JVM, as well as rewriting the Java compiler for performance and correctness. The Scala effort started in 2002, but the community has really been growing since 2006 when a redesigned implementation of the language was released. This week has seen quite a bit of Scala buzz at JavaOne, including an endorsement of Scala as the premier alternative JVM language by Java author James Gosling.

Odersky opens with an argument for a scalable language: one that's suitable for small and large programs, from parsing to scripting, from extension scripts to heavy lifting libraries, one that embraces Domain-Specific Languages (DSLs) rather than a reliance on external languages.

In one sense, Odersky suggests, Scala is a scripting language. It's possible to simply type code into an interpreter and have it evaluated. There can be very little boilerplate code in Scala, and most types can be inferred.

In another sense, Scala is the "Java of the future." Scala boasts most every language feature Java currently has, and many that are still pending or under debate in the Java community, such as closures, traits, and pattern matching. Scala complies down to .class files, and Odersky jokes that he should know, given that he's written two versions of the shipping Sun Java compiler. Scala's performance and operational profile is thus the same as Java's, give or take special cases and the use of alternative libraries.

In still another sense, Scala is a "composition language", one with a new approach to modular systems. In Scala, components are classes or traits that can be composed via mixins. Abstraction is accomplished through abstract members, parameters, or self types; essentially, both functional and OOP metaphors for abstraction are available.

For all that, Scala is trying to avoid becoming a "kitchen-sink language". Scala is comparable in feature count to Java, but has far fewer features than C++ or C#. Scala removes the following from the Java feature set: static members, primitive types, break, continue, special treatment of interfaces, wildcards, raw types, and enums. Scala "concentrates on the glue", not on features. Leveraging abstraction, users can implement the features they need in the language, rather than the language itself supporting every possible use case. The same set of constructs are intended to support both small and large programs.

Scala's lightweight syntax comes from a number of features: semicolon inference, type inference, lightweight classes, extensible APIs, and closures as control abstractions. On average, Odersky predicts a 2x reduction in lines of code between a Java program and a Scala port.

Odersky suggests that "scalability demands extensibility." As an example, he notes all the different data types traditionally used for numerics in programming languages: int, long, float, double, complex, rational, interval, polynomial, etc. While a language could support every possible numeric data type, Scala's extensibility strategy encourages abstractions and additions to existing types and methods to provide new numeric data types seamlessly. For example, it's possible to define + and - methods, essential to dropping in YourFancyNumeric class without pain.

As another example of Scala's extensibility, Oderksy demonstrates adding new control structures. A using method executes a block of operations on a resource, then closes that resource. It's a simple pattern with a short implementation, but the terse code is expressive and requires intimate understanding of Scala's type system to understand what's going on.

Scala makes its scalability claims on the tight integration of functional and object-oriented programming. One of the important concepts here is that functions themselves are objects in Scala. Additionally, Scala offers Erlang-style Actors for high-concurrency programs, contributing to "scalability" in the operational/performance sense.

Like Erlang, Scala provides Actors with mailboxes for messages passed to them. Conventionally, a programmer has her Actors process received messages with a pattern match. Odersky notes that the Actor features of Scala are libraries, not core language features, and argues that this is a testament to the strength of libraries and an extensible approach to language design. Actors in Scala are implemented atop the FJ Framework; the event-driven flavor of Actors (using react) scale up to hundreds of thousands of processes in tests.

The next problem to be solved for Scala is maintaining expressiveness while keeping programs safe and verifiable. A project on "pluggable type systems" is underway, but is unlikely to yield changes to Scala for several years.

Odersky notes a number of companies working in Scala: Google, Buy-a-Feature, Gump-It, Joberator, EDP Training, Reaktor Innovations, Sygneca. Scala tools are improving, from the language's own complier, background complier, and interactive shell to testing frameworks and plugins for all the major Java IDEs. Rounding out, the "official" Scala book will be coming out soon.

Question time!

Are Scala classes open? No, because that defeats static typing. But: mixins, etc.

Does calling into Scala code from Java necessitate reflection? [Answer not captured, sorry.]

How stable is the language and what's the path for future features? We've agreed to slow the development of the language. There will be a standard distribution and an experimental branch.

Is there a project to add Scala support to the Java compiler so you can mix the two languages in the same project/file? Yes! Eclipse has this working to some degree, other projects are underway.

Because of the unconference format, more questions will be asked of Martin throughout the day and the Q&A session was cut short.

Feb 17, 2008

On Side-Projects

Side-projects are important to every programmer I admire. Google's much-publicized 20% time is a corporate codification of the importance of side-projects; even a company that's worth billions knows that you can't keep good people working on the same thing all the time.

Side-Projects and You

There are lots of good reasons to always have some side-projects going:
  • Projects keep you learning. New programming languages, new technologies, new ideas.
  • Projects are mentally refreshing. Taking a step away from the problems you normally deal with is relaxing, and can lend a new perspective on how you work.
  • Projects can be fun. Fun is fun.
  • Projects can be profitable. Little ideas can turn into products and services that people want to pay for (or at least click ads on). Unusual ideas can forge new markets.
  • Projects make you friends. Getting involved with a community is rewarding personally and professionally.
All that may seem obvious if you've made a habit of having side-projects, but I'm always surprised by how many people don't bother. But then, you don't hear about those people because they don't blog, attend meetups and conferences, or generally do things that would make them visible. Side-projects are a sign that you care. They're something we ask about when interviewing at Twitter.

Side-Projects and Me

I've had two side-projects on my to-do list for ages. The first and oldest is Peeramour, which is more or less a dating site for bloggers that emphasizes one's existing online presence rather than requiring yet another half-baked profile. I've been wanting to build this for about the last three years. Peeramour was conceived to scratch a personal itch, but I think there's a business opportunity there too. It's also something that I think would make people happy, and I feel an obligation to give something back to the web community that's been so good to me. Peeramour isn't hard to build, but I want to build it right, both aesthetically and technically.

The second project I've wanted to work on is Quotidian, a Mac OS X (Cocoa) application with which you can store, tag, and organize your favorite quotations. I've also considered building a web compliment to Quotidian that would allow you to share your favorite quotes with friends and interested strangers, but Trsly pretty much gets this job done to my satisfaction. My goal for Quotidian is mostly educational: I use a Mac every day, but I have a relatively limited sense of how I'd build a native Mac tool for myself to use. I'm also concerned that too many of my eggs are in the web-programming basket. Web apps may be vogue, but desktop application programming isn't going to disappear any time soon. It's tough to be a skilled generalist, though, and while I've learned a bunch of theory about how to write Mac software, I haven't had time to get into the nitty-gritty with this project. Once again, the difference is between doing it and doing it right, and the latter requires a ton of knowledge about a development platform with a nearly 20-year heritage.

One of my old side-projects, acts_as_sanitized, has been forked and surpassed (with my hearty blessing) by xss_terminate, written by Luke Francl, who's blogged about it here. acts_as_sanitized was released just before I got swamped by work on Twitter, and I owe Luke for making it something useful again. It's a lesson in the value of open-sourcing, and it leads me to what follows.

Side-Projects and Twitter

Working at Twitter is more than a full-time job. As I mentioned in a previous post, we're still a very small technical team (presently five people writing code and two looking after servers). There's always something work-related I could/should be working on, which means that there's basically no room in my life for guilt-free side-projects. No surprise, right? We're a startup.

One of my goals is that Twitter gets big enough that we have room for side-projects. Right now it just doesn't make business sense. We barely have time to open-source projects like Starling that can benefit from the community's support, much less to code up our own off-the-wall ideas. Compared to our peers in the Bay Area Ruby community we open-source a pathetic amount of code, and I'm eager for that to change. Part of making that happen is approaching our internal goals with the idea that the solutions need to be generic enough that they can be readily opened-up to outside contribution.

The people I'm really excited about working with are all big open-source contributors, and I don't think I'm alone in that. As part of scouting for talent becomes evaluating open-source work, it's going to become a standard part of every good company's growth to standardize policies around open-source contribution and side-projects. After all, Twitter started out as a side-project, which pretty much says it all.

Dec 25, 2007

Comparative Languages: Community is Everything

Over the past year one of my main technical interests has been exploring and comparing various programming languages. I'm not exploring the boundaries of linguistic obscurity like Steve J; I want to borrow ideas from other languages that I can incorporate in my daily work and evaluate potential future tools. (Any programmer who's satisfied with her tools isn't paying attention.)

There are endless metrics against which one can judge a programming language: the performance of programs, subjective readability, availability of libraries for common tasks, availability of quality language primitives, &c. In my explorations, however, nothing matters more than the community surrounding a language when determining its overall success.

A Happy Place

People program in Ruby because it's fun; it makes developers (of a certain persuasion) happy. Happy developers evangelize, and thus a friendly, productive community has grown up around Ruby and Rails over the last several years. Coming from the world of Java or PHP, the Ruby community is some brilliantly green grass. Rubyists tend to be pleasant, articulate, and helpful. That people write cogently about Ruby is perhaps the community's greatest strength, and one that will surely be tested as the community swells with bulk-rate developers.

A Chilly Place

2007 has been a big year for the visibility of functional languages like Lisp, Haskell, and OCaml, but no accessible community has yet formed around any of them. Indeed, by some accounts the functional language community can be downright hostile. In my experience, functional programmers can be a dry and academic lot. Languages don't take off until someone with a sense for humane aesthetics starts evangelizing in a format that people enjoy consuming. While Paul Graham has waxed poetic about Lisp, it'll take more than his essays to warm people up to the functional way of thinking.

A Scala Place

Former Java heads with an eye towards the more practical aspects of functional languages are flocking to Scala which, as mentioned in my previous post, runs atop the JVM. Scala, much like ECMAScript 4, has the potential to be the Next Big Language. It's got constructs to handle most any style of programming, a superb approach to concurrency, and much more. What may tie Scala down are its deep roots in the Java community.

That Scala builds on the strengths of the JVM and the plethora of available Java libraries makes good pragmatic sense. It also means that knowing Scala means knowing Java, and in turn dealing with the Java community. That means things like ugly documentation, forums and IRC channels filled with miserable code and incomprehensible language, Sun's endless cheesy marketing, and a pervading sense of enterpriseyness. Java isn't cool, it's Serious Business.

Converts from Java to Ruby haven't made the switch because Ruby is faster, or better at concurrency, or deployable in a broader range of environments, or better supported. They haven't reinvented the wheel in Ruby with new build systems, documentation setups, and libraries because doing so makes good pragmatic sense. Quite the contrary, on all counts. Developers have chosen Ruby because of the community. They've reinvented the wheel so many times over to keep tools within the Ruby community, where things are nice.

None of the above hassles will deter those familiar with the Java community to dive into Scala, and talented developers are already doing so. For developers that have had the pleasure of largely avoiding Java for the past few years, Scala is a harder sell. For us, the Java community is an albatross around Scala's neck. The question is whether Scala's benefits will outweigh that negative.

Dec 20, 2007

Big in 2008: Dynamic Languages atop High-Level Languages

If you'll allow for some generalization, the mainstream programming language stack basically looks like this:

Stack 1


Dynamic, interpreted languages at the top, nitty-gritty close-to-the-machine languages at the bottom. It hasn't always been this way, of course, but that's certainly been the stack for the last few years. Lately, though, something's been changing. There's a new layer on the stack, and now it looks like this:

Stack 2


Now we've got dynamic languages running on top of interpreted languages, and in some cases atop other dynamic languages. Some of these languages at the top of the stack have been in development for years, but my assertion is that 2008 will be the year that they see increased adoption across the industry.

Why?

Abstraction means increasing returns in developer productivity. Implementing a non-trivial language in C is a hellacious challenge; implementing it in a language like Java, apparently less so given the relatively rapid time-to-market of projects like JRuby. Environments like the Java Virtual Machine (JVM) and and Microsoft's .NET Common Language Infrastructure (CLI) are written for performance and portability. Building on a powerful VM or runtime environment allows a language implementor to inherit some powerful traits.

If this trend of was only happening on the JVM and CLI it would be notable but hardly worth going on about. What made me take pause was the emergence of Nu and ruby+objc. Nu looks like Lisp, and ruby+objc will look like Ruby, but the goal is the same: build a language that gets the Objective-C runtime to do the dirty work and focus on a pleasurable syntax and higher-level abstractions. Implementing the language directly on the runtime has the added benefit of doing an end-run around the problems of bridging languages.

Portable runtimes are big engineering efforts, typically the province of the Suns, Microsofts, and Apples of the computing world. It's understandable that big engineering shops would gear their runtimes towards industrial-strength languages like Java, C#, and Objective-C. But there are plenty of projects for which an industrial-strength language is an impediment, not a boon. Having access to a dynamic language on top of your favorite industrial-strength high-level language is an incredibly useful tool in a programmer's toolbox.

Proving the Trend

Runtime-by-runtime, here's a list of the languages at the top of the stack in 2008:

JVM
  • Scala - "a general purpose programming language [...], concise, elegant, and type-safe, [...] smoothly integrates features of object-oriented and functional languages"
  • JRuby - Ruby for Java
  • Jython - Python for Java
  • Groovy - "an agile and dynamic language for the Java Virtual Machine"
  • so very many more
.NET CLI
  • Boo - "a new object oriented statically typed programming language"
  • IronPython - Python on the.NET CLI
  • IronRuby - Ruby on the .NET CLI
  • F# - ML on the .NET CLI, "provides [...] type safety, performance and scripting"
  • really quite a few more, albeit not as many as on the JVM
Objective-C
Even more out there, here are languages implemented atop dynamic languages, some experimental, some practical:
  • Puppet - a "simple declarative specification language [...] written entirely in Ruby" for systems management. We're using Puppet to manage our new cluster at Twitter.
  • RLisp - a Lisp implemented in Ruby
  • Bus Scheme - "a Scheme written in Ruby, but implemented on the bus!
  • PyPy - Python implemented in Python (but it's actually way more than that)
At any rate, something to watch in aught-eight. I'd be interested to hear if any of the above languages are on your radar.

Nov 30, 2007

Minimalism in Code

The minimalist aesthetic is under-applied in the culture of software development. Thankfully, the benefits of its application haven't gone unnoticed.

Inspiration

For starters, I was happy to see that there's a Wikipedia entry on computing minimalism. The programming section is a bit under-developed, though (ironically).

Steve Dekorte, author of the beautifully minimal Io language, is one of my daily inspirations for minimalism in programming. His clear appreciation of minimalist art, architecture, and design is reflected in the aesthetic of his code.

suck less is aggressive in their stance on simplicity. From their "about" page:
"[I]ngenious ideas are simple. Ingenious software is simple. Simplicity is the heart of the Unix philosophy. The more code lines you have removed, the more progress you have made. As the number of lines of code in your software shrinks, the more skilled you have become and the less your software sucks."
While djb's software may not be simple to use, the design philosophy of his software is in keeping with a minimalist aesthetic. It's no coincidence that his tools have a reputation for stability and security.

judd_stack.jpg

Interpretation

I enjoy programming in Ruby, but it doesn't have the crisp simplicity that I prefer. Syntactical shortcuts inherited from Perl combined with upteen different ways to write a given expression make the language extremely flexible, but also extremely complex. It's possible to write clean, minimal Ruby, but such code rarely takes full advantage of the language. Idiomatic Ruby is powerful but complicated. While Ruby programs are often shorter than their equivalents in other languages, line density frequently offsets length for rapid comprehension.

Like most programmers I know, I'm debating about which functional language to invest some time in mastering. I'm more interested in OCaml and Erlang than Haskell, but none of their syntaxes fit a minimal aesthetic. Lisp couldn't be simpler syntactically, but a page of Lisp code lacks the instant clarity of one in Python or Smalltalk.

Minimalism in code is more than just syntax. It's something deeper down, a rigidity, a quiet enforcement of enjoyable rules. It's the sense of a well-constructed foundation, the same sense I get from looking at a Mies building or the sculpture of Donald Judd. That's the feeling I want from my tools. A kind of implicit trust.

Oct 20, 2007

Getting Started with Scala and Liftweb

I've had an ongoing dilemma when sitting down to work on Peeramour. I could write the site in Rails in an afternoon, which is tempting. Thing is, I write Ruby/Rails code all day. I'm burnt out on it. Plus, I'd like to learn something new if I'm going to be programming in my off-hours.

Looking around the landscape of web application development, only one technology has really caught my eye: Liftweb, a framework built with the Scala language, which in turn runs on the JVM. I like that both Lift and Scala borrow successful ideas where appropriate. I like that both are built with performance, scalability, and ease of deployment in mind. Most of all, though, I like that neither Lift nor Scala is particularly sexy. It's just ugly enough to work.

Getting started with Scala on Mac OS X 10.4 is pretty straightforward:

  1. Download either the Gzip or Bz2 Unix tarballs from the Scala downloads page.

  2. Unpack your tarball of choice and put it somewhere sensible like ~/src/scala.

  3. Add the path to the bin directory to your shell's PATH.
You should now be able to run scala, type in some arithmetic expressions, that sort of thing. Hunky-dory. Now let's get Lift-ed.
  1. If you've got MacPorts (and you should), do a sudo port install maven2. Maven is a build system for big honkin' Java projects, and it takes care of grabbing dependencies and all sorts of junk.

  2. Now, grab the actual liftweb source from Subversion. The packaged versions are old.

  3. Pop into your new liftweb directory and do a mvn install. It'll take a few minutes while Maven grabs and builds this and that, but at the end you'll have built all the examples and whatnot.

  4. A basic blog built in liftweb can be found in sites/hellolift. Head over there, run maven jetty:run and you can poke around at a real actual Lift app.
Instructions for starting your own liftweb project can be found at the developer's blog. Though that post was written in June, the invocations therein still work.

I'm used to working in TextMate, but the only Scala bundle out there is pretty immature. I'm not after a bunch of IDE fanciness, but good syntax highlighting is a must. I imagine things are more hospitable in Eclipse, but that way perdition lies. My next step is to check out the vim support.

Now that I've got a reasonable working environment, tomorrow I'm going to take a stab at some actual code.

Oct 4, 2007

Yet More on Cocoa Development with Ruby

Just after the Mac development love fest that was C4[1], my interest in writing a Cocoa application was piqued. Not being an Objective-C developer (nor having any real incentive to become one), I looked around at the alternatives and saw two different options for Cocoa development with Ruby: RubyCocoa and RubyObjC. After picking the brain of Tim Burks, documenter of RubyCocoa and author of RubyObjC, I was more confused than ever about how to proceed.

Tim has since released a language called Nu, designed exclusively to build on and bridge with Objective-C. As part of his rationale for the new language Tim outlined the problems inherent in bridging Ruby and Objective-C. Phrases like "overlapping", "inconsistent", and "incompatible" litter the document. 'Nuff said.

Nu looks neat. I built it up from source, ran the demos, and poked at the shell. It's got a good vibe to it. But the problem for me arises in the FAQ, in response to the hypothetical, "Can I use Nu without knowing Objective-C?":

"No, at least not if you intend to use it to write Cocoa applications. In my experience, it is a mistake to think that you can use Cocoa from any higher-level language if you don’t understand what’s happening at the Objective-C level."
So in order to really use Nu I need to learn Objective-C, Lisp, and Nu itself. All things I'd like to know... except, uh, Objective-C, which I was looking for an alternative to in the first place.

I understand the challenges in using a language bridge without understanding the languages on each side of that bridge. I suppose that redefines what I'm looking for: not a bridge that lets me interact with a toolkit like Cocoa, but a toolkit that supports multiple languages without having to build them from the ground up.

Oct 2, 2007

Notes From Geeksessions: Beyond the Database

Below are raw notes from tonight's Geeksessions event in San Francisco. All told, while the speakers did fine, I wasn't wowed with the content. See for yourself.

Josh Fergus from Sun

  • “the pro-RDBMS guy”

  • relational dbs good for some things (security), not others (scalability)

  • data is “durable”: survives changes to the application

  • not really much to say, use dbs for what they’re good for

Chad Walters from Powerset on Giant Scale Systems

  • ACID means constraints

  • SQL is hard to grok at scale

  • talking about very large computational domains delivered at very high volumes

  • use a ton of commodity hardware to overcome failures

  • “modern rdbms don’t deliver on reliability”

  • replication starts to be a headache with rdbms

  • use something like GFS or Hadoop that was designed for the task

  • why the application/db divide?

  • “move the computation to the data” – MapReduce, specialized data structures

  • sounds in general like a digestion of the Google approach

Paul Querna from Bloglines

  • BloglinesFS: “store every blog post ever”

  • currently storing several billion posts

  • inspired by MogileFS and GFS, but different

  • two main components: PodServer (serves metadata) on ItemDBs (storage nodes)

  • PodServer: stateless, finds nodes on startup, provides cross-data center replication, “spigots” for dumping data

  • ItemDB: serves web sites as “chunks”, local indexes for for attributes like Date, Post URL, etc.

  • request goes from app server to PodServer to ItemDB

  • crawler writes to PodServer which then writes to ItemDBs

  • 75 data machines of 2×300GB disks, one ItemDB per disk, no RAID

  • crawl all blogs every 30 minutes, thousands of concurrent reads + writes per second

  • “we’d do it all over again because there aren’t any choices out there”

  • Hadoop too specialized for web search, not good for write-heavy data

  • goal isn’t to build an open source project, but to launch a product

Arnold Goldberg from eBay

  • “eBay by the numbers” (not talking about PayPal, Skype, just eBay ecommerce platform)

  • tons of users, transactions, listings, api developers

  • 600 database instances, 20 billion sql statements per day (95% reads), 5600 active tables, 1.8 petabytes

  • original pattern: separating writes and reads: write once and replicate to many

  • “replication will kill you if you try to do it at scale [...] it’s a mess”

  • new pattern: lookup host finds where your data lives (by primary key)

  • use persistent database connections, but know the costs: each connection takes a process/thread

  • figure out where your “scalability cliff” is and test

  • connection concentration tier was a pain

  • to scale, vector based on what you’re looking for and distribute

Aug 28, 2007

More Erlanging

One of my favorite reads from my infosec days was teenage mutant ninja hero coders, a blog by computer security expert Maximillian Dornseif. Dornseif usually says smart things and you should probably be reading him.

Lately, his subject matter has turned to more general programming topics and distributed systems. Dornseif wrote about Erlang's unsubstantiated reliability claims recently, and follows up on that today.

Dornseif's point:

"Erlang is an interesting language. OTP is great engineering. Erlang has considerable momentum compared to other languages with unusual concepts. There is no need use 99.9999999% which ring[s] so hollow."
That's pretty easy to agree with.

I've seen two conflicting schools towards the end of figuring out where Erlang fits in the current programming language landscape. One is the ever-popular "right tool for the right job" school, which posits that you build your distributed components in something like Erlang and other components in languages with more mature, easy-to-use libraries. While this is admirable and pragmatic, the downside is that you then have to couple your tools with language bridges or interoperable formats like XML, JSON, or a message queuing standard. The coupling components can be brittle or eat up processing time with expensive parsing and conversion.

The opposing school is well-represented by, again, Russ Beattie:
" [...] I just don't like working with multiple languages at the same time. I much prefer to have one language in my toolbox that I try to use for as much as possible, so that I can avoid time-sapping context changes, re-use code, and become more proficient with each line of code I write whether its on the desktop, in the browser or on the server."
I've known lots of developers for whom a solution isn't a solution if it isn't available in their language of choice. Context-switching can, indeed, be brutal.

At the moment, I'm not ready to take a side. I've always been a multi-linguist, and I see ups and downs to both sides. It's interesting, is all.

Aug 26, 2007

Russ Beattie on Erlang by Way of Java

Java has never been a particularly relevant language to me, despite being the first language I tried to teach myself. I've managed to avoid Java in my work, in my brief college eduction, and in my self-eductation. I've been aware that there's a whole giant word of Java out there in the IT industry but I consider myself privileged to have never been mired in it beyond editing the occasional XML configuration or fixing minor bugs.

I think Russ Beattie's claim that Java needs an overhaul is dead on, but I also liked this observation:

"The reason people are looking at Erlang is not because its beautiful syntax, great documentation, or up-to-date libraries. Trust me. It's because the Erlang VM can run for long periods of time, scaling linearly across cores or processors filling the same niche that Java does right now on the server."
If Ruby supported lightweight green threads, pattern matching, and some of the concurrency paradigms that Erlang offers, nobody would even be looking at the language. While Ruby may yet improve on this front, just about everybody I know who works on large-scale web applications has at least taken a hard look at Erlang, and some are diving right in.