2,924 karma · joined March 19, 2008
Founder, ex-CTO of CircleCI.
email: allen@griffin.com, a at $my-username.com
Also, I would avoid optimizing TTFBugFix the wrong way. You want the system to be easy to fix because it's well designed & documented, not because it's written in a language you already know.
i.e. I want an api call to email a .pdf to a customer, and then have them "click this link and enter your info to pay via checking account". Several kinds of customers, including consulting, would be much happier with a "push" model of paying, than a "pull" model.
Surely that has nothing to do with Java being 20 years old, and Clojure 1.0 being 6 years old?
> Clojure doesn't even win in the one line department against modern JVM languages (e.g. Kotlin).
Example, please.
This could be relevant to you: http://norvig.com/sudoku.html
which is essentially every single production deployment of a SQL database in the last twenty years. That's the problem.
Not really. While your points are all true, the two biggest factors that you can't really escape are 1) your SPA is still a 1 MB download 2) eval'ing 1 MB of JS before rendering is still slower than serving HTML.
SPAs are a better experience, but they're still slower than conventional pages, and I wouldn't recommend their use on high traffic areas of your site, like the landing page.
(and (foo bar) (hello world))In fact, if I knew of a way to decrease the size of the first load, at the expense of making the second load take longer, I'd probably do it.
It's in beta, but contact me if you're interested.
Clojure's immutable datastructures are ~25% slower than standard java, but also eliminate entire classes of bugs.
I'm not familiar with Haskell's immutable data structures, but I'd be very surprised if there's an optimization that hasn't been adopted by Clojure. Rich Hickey put a lot of work into optimizing them.
From that perspective, immutable structures should be the default, with mutable structures being reserved for when they're truly needed.
Other commenters are speculating that this kind of tool needs to be built into the language, and planned ahead of time. IMO, this is completely wrong. core.typed fits surprisingly well into the language, and there are no fundamental reasons in Clojure or core.typed preventing it from working well.
I largely agree with the criticisms raised in the post, but it's worth pointing out that core.typed is developed by one guy, part-time while working on his phd. The problems are all related to maturity of the project, and bandwidth. core.typed's version number is currently 0.3.11, which gives you an idea of its state.
Ambrose has shown what is possible; I'm confident that with more help, core.typed can become an amazing tool for finding bugs in production code.
They host The International (TI), the biggest tournament of the year. Dota is free to play, and financed by selling in-game cosmetic items. Every year around TI-time, Valve releases a collection of items, with 25% of proceeds going towards the tournament prize pool. Some people buy the items because they look cool. Some people buy the items because they "want to support esports". It turns into a virtuous circle because e.g. reddit gets hyped up like a kickstarter "how high can we make it go?!". Each year breaks the previous sales record, leading to PR, and higher sales. Higher sales leads to a larger prize pool, leading stories like these. Larger prize pools also attract pro players from other esports, leading to more PR and hype, etc.
Interestingly, Sumail is 50th, w/ $300k. The next highest pakistani is $500.
It's also worth pointing out that Dota is somewhat skewed in terms of earnings. Most of a Dota player's income comes from tournament prizes, as opposed to say, corporate sponsorships, which are more popular in Starcraft. This has lead people to claim that SC2 earnings are probably understated, because their sponsorship revenues aren't public.
The top 5 players on this list are from the Dota team that won The International (TI4) last year, so it's a good bet that the winners of TI5 next weekend will be the highest paid players in esports.
Just because the page loads quickly on your laptop doesn't mean it loads quickly for everyone. I'm working on a tool to measure this stuff: https://rasterize.io/blog/speed-objections.html, contact me if you're interested in early access.
Contact me if you're interested in an early preview.
> Is there a way to automatically identify the diffs between your codebase and what's running in production?
In general, no, because Clojure functions aren't serializable, so it's not possible to get the source for a running function in production. There are hacks [1] and approximations [2], but I'm not aware of anyone running them in production.
> Or did you just review repl logs to see what had changed?
Logging the REPL is possible, but it is far easier to do client side than server side, meaning every dev would have to have it installed, and it's easy to "circumvent" by e.g. SSHing into the production box and running a repl in the SSH terminal. (I don't mean circumvent negatively, just that 'install this tool on every dev IDE and use it at all times' is a somewhat fragile process during a firefight).
Also, the last time we investigated REPL-logging, it was too verbose to be convenient. Most nREPL tooling evals a significant number of expressions to e.g. grab docstrings and function arities, so it's hard to isolate the actual changes made. The difference of a single keystroke is also the difference between "eval this function" and "eval this entire file". If the developer evaled the file, you'd then need to diff the string buffer that went over the wire with the committed file, rather than just saying "oh, Alice eval'd this one fn".
If you have live-patched code that you want to keep, the simplest solution is just push it to production as part of your normal deploy process and reboot all servers, so they're guaranteed to match the committed code.
[1] https://github.com/technomancy/serializable-fn [2] https://github.com/gtrak/no.disassemble
The upsides:
SQL is a horrible language, yet all other noSQL DB also throw away the relational, transactional and ACID features that are great in postgres. Postgres with datalog syntax would basically be a win by itself. Datomic queries are data, not strings. Queries can be composed without string munging, and with clear understanding of what that will do to the query planner.
The schema has built-in support for has-one, has-many relationships, so there's no need for join tables.
I've never met a SQL query planner that didn't get in the way at some point. If needed, you can bypass the query planner, and get raw access to the data, and write your own query.
You can run an instance of it in-memory, which is fantastic for unit tests, so you don't have Postgres in production, but SQLite when testing.
The downsides:
It's closed source.
Operationally, it's unique. Because it uses immutable data everywhere, its indexing strategy is different. I don't have the experience of what it will do under high load.
The schema is 'weaker' than say, postgres. While you can specify "this column is type Int", you don't have the full power of Postgres constraints, so you can't declare 'column foo is required on all entities of this type', or "if foo is present, bar must not be present", etc. It should be possible to add that using a transactor library, but I don't think anyone has done serious work in that direction yet.
Compound indexing support isn't in the main DB yet. I had to write my own library: https://github.com/arohner/datomic-compound-index
Of course, just like the current state of affairs, your library has to not thwart advanced optimizations (using eval, accessing properties by strings, etc).
Transducers are mostly function and function composition, but with a specific signature. There are a handful of contracts on a transducer, so it is useful to have a name, so you can say "this function takes a transducer" and "this function returns a transducer".
Releases tend to consist mostly of new features, and a small number of bugfixes.
My email is in my profile. Let me know if you're interested in beta-testing.
For example, they cite both schedule/budget pressure, and insufficient docs. The incomplete docs were "thousands" of pages. Does anyone really believe even half the team would read "complete" documentation, that are thousands upon thousands of pages? Would complete docs speed up development time? Would they speed up development time even taking into account the cost of producing and consuming complete docs? Is the size of module truly essential complexity, or is part of the problem that they're building on legacy code?
The author mentions interop with other teams and third party software as a large source of friction. Why are other modules so large and complex that they're maintained by separate teams? Is that essential complexity, or was it caused by previous attempts to patch their way to release? Would the modules be more manageable, and hence, require smaller teams, if they used other practices/languages/tools?
Access to test hardware, and managing the test personnel was another source of friction. What is the cost of buying more test hardware? In previous companies where I've worked, with manual QA depts and under-funded test hardware budgets, doubling the hardware budget would allow halving the QA salary budget (primarily because you don't need to hot-swap equipment several times a day), and shorten test cycles. Is that the case here?
Further, how much manual test is truly necessary, and how much is caused by the developers not writing automated tests?
I find GA's UI to be absolutely terrible. I plan on having better UI, more detailed performance breakdown, and alerts / monitoring.
I'm also treating this more as a production monitoring tool, rather than a dev tool.