[HN Gopher] Lichess gets a big upgrade. It doesn't go as planned
___________________________________________________________________
Lichess gets a big upgrade. It doesn't go as planned
Author : _fizz_buzz_
Score : 259 points
Date : 2022-12-15 17:07 UTC (5 hours ago)
(HTM) web link (lichess.org)
(TXT) w3m dump (lichess.org)
| TulliusCicero wrote:
| > Improved type inference
|
| > We want types, not boilerplate. Sometimes it's best to let the
| compiler figure out what things are by itself.
|
| At first I thought type inference was cool too, but more and more
| I don't like it. I prefer being able to see a variable's type
| easily, even when skimming over code. Type inference makes code
| less readable to me.
| Barrin92 wrote:
| that's more an issue of editor integration. F# in Vscode for
| example overlays what types it has inferred automatically.
| TulliusCicero wrote:
| And what happens in every other tool that displays source
| code?
| TylerE wrote:
| Who cares? That's the point of an integrated editor...
| blt wrote:
| yeah, to be fair I only know it through the C++ `auto` keyword,
| but I dislike its overuse. It's great for weird templated
| iterator types but I prefer to see the concrete type if it's a
| reasonable length.
| beached_whale wrote:
| With C++'s implicit conversions, it makes that less of an
| issue though. Like a function returning long and assigning to
| an int "just works" and can silently trunctate. With auto,
| both are long
| jandrese wrote:
| Or the question you should always ask: What if the compiler
| gets it wrong? Is there a way for you to tell?
| MaxBarraclough wrote:
| Compiler/runtime bugs are always painful, I don't see that
| type inference is a special case there.
|
| Fortunately such bugs are pretty uncommon.
| jandrese wrote:
| Is it a bug if the compiler thinks that maybe the value
| could grow too large to fit in an integer so it promotes it
| to a floating point type. But then you compare it to a
| value that is converted out of a string of ASCII digits and
| the comparison is off by 1 because 4 != 3.99999999996 and
| this causes your code to iterate one additional loop which
| doesn't cause an immediate problem except about 1 in every
| 256 times it causes a boundary condition where the next
| packet will have a corrupt first byte?
|
| Technically the compiler technically did nothing wrong, but
| you are still left with a head scratcher because all of the
| logic seems sound and yet it produces occasional garbage.
| adgjlsfhk1 wrote:
| type inference isn't magic. It would absolutely be a bug
| for the compiler to change the type of a variable from an
| int to a float because it thinks there will be overflow.
| ben-schaaf wrote:
| > Technically the compiler technically did nothing wrong
|
| I don't know a single language where integers are
| "promoted" to floats when they get large; certainly no
| statically typed language. You could argue JavaScript
| does this, but it's neither compiled nor does it actually
| have integers. So yes, if a compiler did that it would be
| a bug.
| duped wrote:
| What compiler does that? What you're describing sounds
| like a weirdly designed type system, not a compiler that
| implements it.
|
| That said, this _is_ an example of the compiler being
| wrong.
|
| If a value is changed to a data representation with
| different comparison semantics, and later compared to a
| different value of a different representation, it means
| the original optimization (hand wave over the definition
| of that) was unsound in the first place. AOT compilers
| would classify this as a bug that needs to be fixed
| imminently, and JIT compilers that do this kind of thing
| use something called dynamic deoptimization to remove the
| change once its been invalidated.
| treis wrote:
| The problem is when you get things like:
|
| var someLongThing
| <application.someHierarchy.someLongAssPackage.someLongThing> =
| new
| application.someHierarchy.someLongAssPackage.someLongThing()
| hinkley wrote:
| class class1<T extends Comparable<T> > implements
| SmallestLargest<T> T[] values;
|
| This is a spot where inference doesn't work, but has the same
| problem as the relatively tame example you used.
|
| The solution here is not to eliminate the type signatures.
| The solution is not to wait until compile time to figure out
| the type of a thing. Nominal typing, as in named types, is
| the solution here. If you have a 'thing', which also happens
| to be an
| application.someHierarchy.someLongAssPackage.someLongThing
| implements
| application.someHierarchy.someLongAssPackage.someInterface,
| anotherLongAssDefinitionForTheReturnTypes but that's an
| implementation detail, not a type description.
|
| It's an Address, or a customer impression, or a similar
| product, or a fuel tank. Just fucking call it what it is
| instead of pretending like you're working on your PhD thesis.
| Your coworkers aren't robots, or academics, they're human
| beings who've got real work to do and kissing your
| architectural astronaut butt/complementing your farts are not
| on the list. Name things like a human. A wise human, but a
| human.
| rubyist5eva wrote:
| My IDE can show me inferred types as an overlay in my editor
| (even in languages with dynamic types like Ruby, jetbrains
| inference is pretty good when the code is simple), perhaps look
| for an extension for your preferred editor?
| winter_blue wrote:
| If GitHub could dd support for it, then that would be
| amazing.
|
| As it stands, type inference has a tendency to make code
| reviews more difficult.
| rubyist5eva wrote:
| Why Github? I'm assuming you mean their code review
| interface, which is so incredibly lacking I don't even
| bother with it anymore and I just pull the branch locally
| and use my IDE.
| TulliusCicero wrote:
| Then you need that support in every related place, as the
| other comment about GitHub points out.
| vkou wrote:
| Type inference everywhere can make code less readable, but type
| inference when it's clearly the code author's intent that the
| type of the variable should not be of much interest to anyone
| improves readability.
|
| A common example of this is a variable that's initialized in
| one line, fed into another function in the very next line, and
| then never used again. [1] If the function call that produces
| it, and the function call that consumes it is named well, the
| variable's type is often, but not always superfluous.
|
| It's like naming for loop variables. Sometimes, you want a
| specific, detailed name for them. Other times, you just call it
| 'i', because what it is... Is not very important. It's a
| counter, counter goes up until we hit the end of a list, don't
| think about it too much.
|
| [1] The two function calls could have been mashed together, but
| that would make the code less readable. The full variable type
| could have also been included, but its not very relevant to the
| intent of the code - which is simply[2] feeding the output of
| one function as an input into the other.
|
| [2] Obviously, when contextual information (like real-world
| side effects of creating a particular variable - say, a thread,
| or a record...) that complicates the "Create -> Use" case is
| relevant, or if the APIs in question have a lot of function
| overloading, or poorly-named interfaces, or if non-trivial
| casting is going to take place, it may still be beneficial to
| explicitly provide the variable type.
| vlovich123 wrote:
| Type inference w/ overlays is usually enough. The only thing
| I'm missing with VSCode rust overlays is they sometimes don't
| show the lifetime on an inferred type which makes it a little
| more annoying.
| dkarl wrote:
| Explicit types are useful in some places. Type inference
| doesn't mean you can't use them, just that you don't have to
| spell them out everywhere even when they aren't useful.
| spullara wrote:
| I try to avoid using it where the type isn't obvious from the
| context. But when it is, I like it a lot.
| matsemann wrote:
| Type inference locally is great. Doing `val something =
| MyClass()` or `val something = someFunc()` . No ambiguity, just
| less typing and clutter. At bounds however (function
| input/output for instance) I prefer explicit types, less chance
| for mistakes and the signature acts as documentation to what
| the function does.
| 1337shadow wrote:
| Static typing removes freedom I am addicted to with duck
| typing, however, I only ship TDD code which also serve as
| coding documentation. Both are protective but if you're not
| writing tests then by all means use static typing.
| yetanotherloser wrote:
| I'm finding this hard to relate to. Our circumstances and
| experiences must be pretty different. But I'm afraid to me
| that sentence reads a bit like "I have a lathe so I don't
| need a bicycle". You or I might not do bicycle jobs, or
| lathe jobs, but it's a bit of a stretch to imply one
| renders the other irrelevant.
|
| I find it interesting that you characterise static typing
| as about safety. I think it's more about communication.
| (for me this includes "communication to myself when I wrote
| this seven years ago and didn't think about it since",
| which I appreciate may be a bit of an edge case). Tests are
| also a great medium of communication, but a different one -
| in which case the metaphor becomes swap a sonnet for a
| sonata? I'd like both please, but maybe not always at the
| same time :-D
| dmitriid wrote:
| Neither tests nor types are documentation.
| 63 wrote:
| One of the things that's made me the most frustrated learning
| rust is all the type coercion and inferencing. Sometimes code
| will just work when I have the wrong mental model because types
| are coerced but then it ends up biting me later when suddenly
| everything breaks because it can't coerce anymore and I find
| out nothing was the type I thought it was. I wish there was a
| way to turn it off while I'm learning just so I can understand
| what's really happening.
| jgilias wrote:
| Nobody forces you to rely on type inference. It's perfectly
| valid Rust where you type everything if you so wish. This
| might actually be a good way to learn the ins and outs of the
| type system.
|
| EDIT: Also, what do you mean by type 'coercion'? As far as I
| know the types in Rust are never silently coerced to
| anything. They just are what they are.
| seritools wrote:
| > As far as I know the types in Rust are never silently
| coerced to anything.
|
| There are some specific coercion sites and kinds:
| https://doc.rust-lang.org/reference/type-coercions.html
| kibwen wrote:
| True, although coercion in Rust is quite limited (it
| doesn't even coerce smaller ints into larger ones), and
| the coercions that exist are pretty harmless IMO (like
| letting you call a function that accepts a `&foo` if all
| you have is a `&mut foo`). I suspect they're referring to
| something else, as I've never seen coercion highlighted
| as a pain point before.
| vlovich123 wrote:
| They mean inference. Generics get resolved to different
| types (and lifetimes) depending on surrounding code.
| yetanotherloser wrote:
| wow, I never contemplated before whether that kind of
| language design could be evil, but you make me think it
| might be. Maybe not in the ordinary course of sensible
| use, but in some horrible "I didn't think of that". Then
| I feel a bit hypocritical because I'm sure I've relied on
| a hundred more problematic abstractions without worrying
| about it.
| kibwen wrote:
| Far from evil, it's amazingly useful, and is why things
| like `let x: Vec<_> = foo.collect();` work (the return
| type of the `collect` method is generic). Rust stops type
| inference at function boundaries, so the precise type of
| something is never far away if you need it.
| efficax wrote:
| types are not coerced in rust? you have to implement explict
| `From` traits and call `into`.
| tomca32 wrote:
| I think they meant to say "inferred"
| williamscales wrote:
| I've never written rust, so maybe this is way off. But could
| the code editor display the inferred type right next to the
| variable declaration?
| c0balt wrote:
| Most editors (or plugins for them) that support a LSP, like
| rust analyzer[0], can do it. This includes afaik (neo)vim
| (via coc.nvim), vscode (via rust-analyzer extension), emacs
| and Clion.
|
| [0]: https://rust-analyzer.github.io/
| Jorengarenar wrote:
| >(neo)vim (via coc.nvim)
|
| I think _vim-lsp_ and _Neovim 's native LSP_ both have it
| too
| toast0 wrote:
| It could, but then you put off grumpy people like me with
| old editors that don't do that kind of thing. Plus you need
| fancy tools to look at patches. And none of it is going to
| work inside tokio's select macro (or other useful macros),
| which could be a lot of your code, depending on what you're
| writing.
|
| I'd rather work in a language where nobody has type
| information. It's a much more even playing field. ;p
| bryanlarsen wrote:
| What are you using for an editor? Both emacs and vim can
| do that kind of thing.
| toast0 wrote:
| I use joe. I've been using it for 25 years at this point,
| and it works enough, and I'm not interested in changing.
| About 15 years ago, I upgraded to a version of joe with
| syntax highlighting which was pretty cool, but I'm not
| much interested in more than that. I do occasionally poke
| around with things in fancy IDEs (it's easier to fiddle
| with Arduino projects with an IDE than otherwise, because
| nobody writes about how to do the pieces individually...
| but maybe I can drive platform.io from the command line
| in the future), but I'm much happier with a simple as
| dirt editor, and another terminal to run Make in (or
| whatever, using Rust for work now, so running cargo
| instead of make).
| moonchrome wrote:
| IMO a decent editor is a must for statically typed
| languages - it's such a productivity boost to navigate by
| type information, type safe refactoring, etc.
|
| Main benefit of static typing is enabling tooling to
| reason about your code - not using IDEs is throwing a
| huge chunk of it away. Historically it was easy to get
| projects that would be too large for real-time tooling -
| but these days the IDEs got better and you can get 32 or
| even 64 GB ram into a workstation trivially - I haven't
| seen a scenario like that in years.
|
| I've also noticed GitHub supports type navigation in some
| languages, but yeah for nontrivial reviews I'll usually
| do a checkout anyway.
| twicetwice wrote:
| Yes, I believe rust-analyzer language server + vscode
| extension is the setup I have that does this for me.
| cauthon wrote:
| Yes, highly recommend this setup. Displaying inferred
| type + compiler errors has been amazing while learning
| Rust.
| Kukumber wrote:
| The power of open source!
|
| Congrats to lichess and everyone involved who helped!
| d2049 wrote:
| > To be able to tell if Scala 3 itself is faster, we would have
| to rollback to Scala 2 and try it with the proper JVM tuning. I'm
| not willing to do that, sorry! Once you've tried Scala 3, there's
| no going back.
|
| Pardon my ignorance. Why can't you set up a performance test in
| both environments and measure the speed?
| ARandumGuy wrote:
| I think it's a matter of effort. Many performance bottlenecks
| only really show up when you scale up to massive levels. While
| it's possible to replicate that on a test environment, it takes
| time and effort to set that up. While doing that is worth it
| for some applications, I can see why the Lichess developers
| didn't want to bother.
| hocuspocus wrote:
| Time, effort and spare resources that Lichess had better
| allocate somewhere else.
|
| If Thibault enjoys Scala 3 and feels more productive, while
| the overall performance on the same hardware is approximately
| equal, it's already a win for the project.
| agilob wrote:
| Setting up reliable and reproducible performance environments
| is as much work as running good quality prod systems. It
| requires monitoring thing rarely available to monitor,
| extending prod metrics, creating snapshots, running repeatable
| tests on different scales. This isn't work for a single person.
| I'm in a team of 7 working to acquire next customer who will be
| on average 5x bigger than peaks of our current biggest
| customer. We've been designing, configuring and creating
| metrics on EKS since September, alongside training devs and
| developing performance engineering framework in k6. Lichess
| doesn't need that much effort and accuracy, but it's still lots
| of work. Did you know Fargate will schedule you Intel Skylake
| or Broadwell and there's even 30% difference in performance
| between them on certain tasks?
| typingmonkey wrote:
| That would only confirm that the new lichess version is faster,
| but not that scala3 is faster then scala2.
| cpleppert wrote:
| The JVM only runs out of codecache (usually) after a period of
| time running with a production load.
| toast0 wrote:
| > Pardon my ignorance. Why can't you set up a performance test
| in both environments and measure the speed?
|
| Everyone has a performance test environment, not everyone has
| one that's separate from production. In this case, generating
| realistic test patterns is probably very difficult, so you get
| one environment for everything.
| tiffanyh wrote:
| 64 comments a week ago on similar topic ("Lichess on scala3 -
| help needed")
|
| https://news.ycombinator.com/item?id=33865932
| hn_acc_2 wrote:
| Looks like the top comment was spot on. Were HN users the
| "Avengers" mentioned in OP?
| jakub_g wrote:
| For those short on time: "It doesn't go as planned" is explained
| in the middle of the article:
|
| > When everything compiled, I shipped it. And to everyone's
| surprise, apart from a few bugs I had created while rewriting
| thousands of lines of code... it worked. It just did. No
| explosions, no obscure bugs, no memory leak, no performance
| degradation. That was rather unexpected.
|
| ...followed by
|
| > Then we saw the JVM CPU usage rise to alarming heights, with
| unusual patterns. And no obvious culprit in the thread dumps...
|
| > it was just the JVM that needed some tuning.
|
| Details: https://lichess.org/@/thibault/blog/lichess-on-
| scala3-help-n...
| bravetraveler wrote:
| 'if it builds it ships' in action, love to see it
| lamontcg wrote:
| > "It doesn't go as planned"
|
| bit of an editorialized clickbait title really.
| zython wrote:
| INNOCENT dev migrates to Scala 3, what happened next will
| SHOCK you.
| lamontcg wrote:
| Spend a week of running the JVM in production without
| tuning it challenge [IMPOSSIBLE]
| smcin wrote:
| Yes it's clickbait, so I didn't upvote it; an accurate title
| would have been "Lessons learned upgrading Lichess from Scala
| 2 -> 3 and the need to tune the JVM". A drama-free title like
| that would have been fine, and I would have upvoted.
| jonathanyc wrote:
| I agree. Clickbait titles are not universalizable. Kant
| would not be pleased.
| kzrdude wrote:
| The actual title seems to be Lichess & Scala 3 and the
| subhead is "Lichess gets a big upgrade. It doesn't go as
| planned."
| AuthorizedCust wrote:
| JVM tuning is frustrating. The need for that is generally not
| an issue on Microsoft .NET.
| warent wrote:
| moffkalast wrote:
| As an anecdotal case, a company a friend of mine works at has
| a backend workforce of primarily Java-only devs, so that's
| the only thing they can really maintain. There's a lot of
| sunk cost and inertia on the enterprise side when it comes to
| Java.
|
| But yeah for starting something new, with an open language
| choice? No way anyone sane would go for it these days.
| Especially after Oracle basically closed sourced it, making
| JRE distribution illegal.
| warent wrote:
| I take the copious downvotes as confirmation!
| phoronixrly wrote:
| As opposed to what?
| [deleted]
| vlovich123 wrote:
| Machine code. Assembly if you're weak willed and need some
| hand holding.
| [deleted]
| danielheath wrote:
| Written with a magnet, and a steady hand. Keyboards are a
| crutch.
| hinkley wrote:
| Shit the ROMs on the Apollo mission were hand-woven wire
| looms. 4K wires weaving between and around magnets. Why
| hold a magnet when you can use a marlin spike?
| poulpy123 wrote:
| I personally use cosmic focused on a disk by the
| turbulences created by a butterfly to program, but it's
| not a competition
| toast0 wrote:
| Because nobody has ever expanded their machine code
| beyond the L1 cache size and experienced a huge
| difference in performance.
| renewiltord wrote:
| Pathetic. If you can't fit your code into L1, are you
| even a real programmer? No one has time for your Electron
| shit. Get real, bruh, what's your deadlift?
| nurettin wrote:
| Back in my day we didn't have L1, so our code just ran on
| 16 registers.
| tux3 wrote:
| Of course _real programmers_ write forged microcode to
| define just the machine code instructions they need, and
| they flash the ucode update live in prod to deploy their
| app.
|
| But if you're weak willed and need some hand holding, the
| official ISA's machine code is tolerated too.
| [deleted]
| toast0 wrote:
| I mean, I'm not a JVM fan, but this sort of thing happens in
| lots of languages, and even operating systems. Upgrade from
| version X to X + 1, especially with lots of changes in
| everything else, and you're bound to hit different limits or
| explore the interface with limits you were hitting and didn't
| realize.
|
| The other option is to never update anything; which is valid,
| but painful.
| amackera wrote:
| JVM is easily one of the best runtimes out there by any
| objective measure.
|
| (JVM != Java, remember)
| smeagull wrote:
| Hubris. I've seen shops build servless applications with Java
| because "we have java developers".
|
| I left that contract very quickly.
| winrid wrote:
| Is this really an issue with graalvm?
| WhiteBlueSkies wrote:
| I wonder how node.js would have performed at that scale.
| jbm wrote:
| I truly wish I could get Opaque Types (Newtypes?) in Typescript.
| Great writeup!
| stareatgoats wrote:
| Got sucked into reading the article because of the "didn't go as
| planned" but it left my thirst for failure stories unquenched.
| Should have known.
|
| That aside, that thing with opaque types in Scala sounds
| interesting - but how would the compiler know that the parameter
| was a UserId and not just a random string?
| lmm wrote:
| You have to explicitly call something like UserId(...), just
| like with any other type. (You can actually do this technique
| in C by using a 1-element struct, although it's a lot more
| cumbersome than Scala since the type system is so much more
| limited).
| exabrial wrote:
| -1 for Type inference and `var`. It literally save you no time,
| increases cognitive load, and is an exposure point for future
| bugs.
|
| Just use Explicit types. They aren't hard, time consuming, or
| bad. They are your friends.
| syastrov wrote:
| > That's where things got a bit hairy. Lila is built on Play
| Framework which is not yet ported to Scala 3.
|
| > So I forked it and butchered it to remove everything we don't
| need - which is actually most of the framework.
|
| I guess there is hope that Play framework itself will be migrated
| to Scala 3 and that the dependency on the fork can be removed,
| but this is taking on a risk - what if there are security updates
| to the upstream in the mean time?
| 12345hn6789 wrote:
| Isn't light bend more or less falling apart? I thought they
| announced they would no longer publish changes to play
| tasuki wrote:
| I think the plan might be to get rid of the play framework
| altogether and rather use a couple small, independent libraries
| to achieve the same.
|
| The likelihood of getting security fixes in the future is about
| the same as getting new security holes created by whatever
| updates. Butchering away everything they didn't need certainly
| didn't harm security.
| eppp wrote:
| But what was the JVM tuning? Thats the most interesting part!
| lukhas wrote:
| Currently it's "-Xms30g -Xmx30g -XX:+UseG1GC
| -XX:+PrintCodeCache -XX:ProfiledCodeHeapSize=500m
| -XX:NonProfiledCodeHeapSize=500m -XX:NonNMethodCodeHeapSize=24m
| -XX:ReservedCodeCacheSize=1024m -XX:InitialCodeCacheSize=1024m
| -XX:ParallelGCThreads=24"
|
| Everything after G1GC was suggested by various helpful experts
| on HN, Discord, by email and other media.
| csunbird wrote:
| Are you running the whole lichess on one machine, or is this
| one shard only? 30 GB RAM for one instance of application
| seems very high. (sorry did not have time to read the whole
| article yet)
| Buttons840 wrote:
| Is there any other runtime that needs as much tuning as the
| JVM?
|
| It seems like a failure of the JVM that someone capable of
| porting thousands of lines of code with little trouble then
| fails to tune the JVM. It's like, "we wrote all the code, now
| the hard part starts, tuning the JVM".
| lmm wrote:
| I took just the opposite lesson from this: the JVM offers
| enough turing knobs that in the rare, extreme cases where
| the defaults don't work for you (I suspect few single-
| server workloads in the world have the combination of
| complexity and request rate that Lichess does), there are
| still ways to do something about it. If he'd been using,
| say, Go, he'd probably have had to give up and roll back,
| or patch the runtime code.
| hellcow wrote:
| I've been using Go for 7'ish years across a large
| codebase, comprising multiple services interacting with
| millions of people.
|
| Every release Go gets better and requires 0 changes to
| the code. I have never needed to fine-tune the GC. I have
| never needed to spend a month rewriting my code to work
| with Go 2.0. I have never been nervous to update to a new
| Go version. I write the code once, and it runs great in
| prod for years. I love and value these things. I also
| suspect that Lichess's use case would perform extremely
| well in Go out-of-the-box, since it's just a web app.
|
| I certainly hope the JVM team would like Lichess and
| other web apps to run well without needing arcane
| configuration knowledge gathered over years of experience
| and battle scars in production.
| kinjba11 wrote:
| > or patch the runtime code
|
| A huge spike in CPU usage would be treated as a
| regression in other language runtimes and would likely be
| addressed. The fact that this is solvable with advanced
| JVM knobs is both good and bad. Good in the way you say.
| Bad because the complexity of maintaining all those knobs
| makes it difficult if not impossible to improve the
| runtime defaults, and every runtime problem becomes a
| tuning problem.
| thomashabets2 wrote:
| Java is a language built up of failed experiments in
| language design.
|
| My full rant about it is
| https://blog.habets.se/2022/08/Java-a-fractal-of-bad-
| experim...
|
| It's partially my subjective opinion, but it seems that
| almost every single language design decision that Java made
| was, in retrospect, a bad one.
|
| Not that I could have done better. It's just that none of
| it panned out.
| jdlshore wrote:
| Eh... your hate is blinding you.
|
| Java was the first mainstream garbage-collected language.
| Not the first GC language, but the first one to get
| serious traction. It started the post-C++ era.
|
| That was a pretty bold design decision for the time, and
| one that worked out. The VM was another big one, and it
| also worked out.
| adgjlsfhk1 wrote:
| That's not quite fair. They made 1 good design decision
| (killing pointers).
| esaym wrote:
| Perhaps it is different now, but I've always hated how to
| figure out how much memory a java app needs. You can
| certainly give it 30GB of ram and it will happily use it
| all up and then start making garbage collection calls. But
| does it _really_ need all that ram? I think the best
| practice of the time was to continually lower your max heap
| amounts until you started getting allocation errors, then
| bump your number up by 20%-50% (or something like that).
| stardenburden wrote:
| The linked blog post has some details:
| https://lichess.org/@/thibault/blog/lichess-on-scala3-help-n...
| csense wrote:
| Also see previous HN discussion (top comment is the
| solution):
|
| https://news.ycombinator.com/item?id=33865932
| cpleppert wrote:
| Yeah, literally the first thing you do when running into
| JVM issues. It was my second initial suggestion in Discord
| as well.
| xyst wrote:
| Would be interesting to see if this application would benefit
| to switching the JVM from openjdk to Azuls "high performance"
| JVM.
|
| Rather than use a big bang deployment. Setup an A/B test, and
| gather a sampling of data.
|
| I haven't been able to truly test azul's claims yet. Java
| apps that I manage/deploy were on a small scale in regards to
| requests/sec and I personally didn't see much difference.
| philipwhiuk wrote:
| > Significant indentation and optional braces
|
| And this is why it's annoying to use Scala. They just decided to
| rewrite the syntax of the language
| tasuki wrote:
| In Scala, eg 2.13 is a major version. Scala 3 is like a super-
| major version and still it's backwards compatible with 2.13:
| the new syntax is fully optional.
|
| Which languages don't make any changes to syntax over major
| versions?
| spiderice wrote:
| I'm not against syntax changes, but significant indentation
| seems like an insane choice to make. That's been a thorn in
| the side of Python for decades. Even if some people do like
| the look of it, it doesn't seem worth the tradeoffs.
| civopsec wrote:
| It's not a problem for Haskell and Scala is closer to
| Haskell.
| hocuspocus wrote:
| Like many seasoned Scala developers I was skeptical at first
| but it's actually pretty enjoyable despite a few
| inconsistencies. Jumping between Scala 2 and 3 codebases isn't
| much of a problem. Granted, it makes the life of people working
| on tooling significantly more complicated but I'm not one of
| them.
|
| The decision was directly motivated by Odersky's experience
| teaching Scala to students for 15+ years, it wasn't made for
| the sake of fueling drama in the community.
___________________________________________________________________
(page generated 2022-12-15 23:00 UTC)